home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 60.zip
/
BS1 part 60
/
LSD 32.adf
/
AmigaGfx1.pp
/
AmigaGfx1
Wrap
Text File
|
1990-09-07
|
184KB
|
4,921 lines
_________________________________________________________________________
/#########################################################################\
|#####...####..######..######......####...####..#####..##......##......###|
|####.....###..######..########..#####.....###...####..##..######..#######|
|###..###..##..######..########..####..###..##....###..##..######..#######|
|###..###..##..######..########..####..###..##..#...#..##..######......###|
|###.......##..######..########..####.......##..##.....##..######..#######|
|###..###..##..######..########..####..###..##..###....##..######..#######|
|###..###..##...#####...#######..####..###..##..####...##..######..#######|
|###..###..##......##......##......##..###..##..#####..##......##......###|
|#########################################################################|
|####################################################################{RB}#|
|=========================================================================|
| |
| ----> PRESENTS <---- |
| |
| AMIGA GRAPHICS INSIDE AND OUT - THE COMPLETE BOOK |
| |
| > PART 1 < |
| |
| Typed / Scanned / Edited By : RAZOR BLADE. |
| Additional Typing by : GLITCH ( + 8 pages by Asterix ! ). |
| Original Supplied by : VIPER |
| |
|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
| CALL THE ALLIANCE WORLD HQ -> THE PLACE TO BE |
| UNKNOWN PLEASURES --> +44 (0) 823 322 891 --> SYSOP: BARBARIAN |
|_________________________________________________________________________|
TABLE OF CONTENTS.
Introduction ix
1. Amiga Graphics 1
1.1 Setting pixels with PSET 1
1.1.1 Using the mouse and PSET:a simple drawing board 1
1.1.2 Rosette and Garland Patterns 2
1.1.3 Erasing Pixels 3
1.1.4 Adding colour to your screen 4
1.1.5 More about PSET and PRESET 6
1.1.6 The opposite of PSET: the POINT statement 7
1.1.7 Relative Addressing 8
1.2 The LINE statement 10
1.2.1 The power of LINE 10
1.2.2 The Moire effect 10
1.2.3 Quix, Lines galore 11
1.2.4 Function Plotter 12
1.2.4.1 Function Plotter modes and menu controls 15
1.2.4.2 Undefined function values 16
1.2.4.3 Scaling 16
1.2.5 Drawing Rectangles 17
1.2.6 Relative addressing with the LINE statement 18
1.3 The CIRCLE statement 20
1.3.1 The aspect ratio 20
1.3.1.1 Animation using CIRCLE 21
1.3.1.2 The aspect ratio in circle formulas 23
1.3.2 Angle parameters with CIRCLE 24
1.3.3 Relative addressing with CIRCLE 25
1.3.4 Pie Charts 25
1.3.5 Pixels and lines with CIRCLE 27
1.4 Area fill 30
1.4.1 The PAINT statement 30
1.4.2 Another solution: AREA and AREAFILL 31
1.4.2.1 Different modes of AREAFILL 33
1.4.3 Patterns 34
1.4.3.1 Pattern Creation 34
1.4.3.2 Patterned Areas 35
1.4.3.3 Pattern Design in a program 36
1.4.3.4 Patterns and the Cursor 38
1.4.3.5 Bringing it together 39
1.5 Medley of colours 41
1.5.1 The complete palette 42
1.5.2 changing RGB colours 42
PAGE iii
----------------------------------------------------------------------------
1.5.3 The opposite of PALETTE 43
1.5.4 Animation using color 44
1.6 All about PUT and GET 46
1.6.1 Using PUT and GET 46
1.6.2 Saving to Disk 48
1.6.3 Alternate uses for PUT 50
1.6.3.1 Default mode of PUT 50
1.6.3.2 A direct method using PSET 52
1.6.3.3 Inverting graphics 52
1.6.3.4 AND or OR 53
1.7 Animation in BASIC 55
1.7.1 Sprites and bobs 55
1.7.2 The OBJECT.SHAPE statement 56
1.7.3 Designing an object 56
1.7.4 The complete object editor: Eddi II 56
1.7.4.1 The screen 68
1.7.4.2 Object size 68
1.7.4.3 Depth 69
1.7.4.4 Colors 69
1.7.4.5 Drawing 69
1.7.4.6 Loading and Saving 71
1.7.4.7 Testing Objects 71
1.7.4.8 Exiting Eddi II 71
1.7.4.9 Loading objects into your programs 72
1.7.5 Flags 72
1.7.5.1 The SaveBack flag 72
1.7.5.2 SaveBob 75
1.7.5.3 Overlay 75
1.7.5.4 The shadow mask 75
1.7.5.5 Collisions 76
1.7.5.6 Animated bit-planes 80
1.7.6 The alternative: sprites 85
1.7.6.1 The small difference 85
1.7.6.2 Color and Sprites 85
2. The amiga operating system 87
3. Intuition - the user interface 93
3.1 Intuition windows 93
3.2 The window data structure 96
3.3 Functions of the intuition library 106
3.3.1 A personalised mouse pointer 106
3.3.2 Moving windows made easy 109
3.3.3 Setting Window Limits 110
3.3.4 Sizing Windows 111
3.3.5 WindowToFront and WindowToBack 113
PAGE iv
----------------------------------------------------------------------------
3.4 The Intuition Screen 114
3.4.1 Screen Structure 115
3.4.2 The Intuition functions for screen handling 118
3.5 Intuition and the rest of the world 120
3.6 The RastPort 122
3.6.1 RastPort data structure. 123
3.7 Graphic Primitives 129
3.7.1 Multi-colour patterns 129
3.7.2 Shadows using Cursor positioning 140
3.7.3 Outline print - a special flair. 143
3.7.4 Text Styles 144
3.8 The RastPort and the graphic system 148
3.9 The Bit-Map structure 149
4. The ViewPort 151
4.1 The ViewPort data structure 153
4.2 The graphic modes of the Amiga 155
4.2.1 The Halfbrite mode 156
4.2.2 The hold-and-modify mode: 4096 colours 161
4.3 The ViewPort in the system 166
4.4 View: The graphic brain 168
4.5 Copper Programming 175
4.5.1 Double buffering for lightening fast graphics 175
4.5.2 Programming the Copper yourself 180
4.5.3 Programming 400 simultaneous colours 185
4.6 The Layers : Soul of the windows 188
4.6.1 The Layer data structure 191
4.7 The different layer types 196
4.7.1 Simple Layers: your own requester 197
4.7.2 The superlayer: 1024 * 1024 pixels 199
4.7.3 Permanently deactivating layers 205
4.7.4 Using the BASIC commands within a layer 206
4.8 Layers in the system 212
5 The Amiga fonts 213
5.1 The Amiga character generator 214
5.2 Opening your first font 218
5.3 Accessing the disk fonts 221
5.4 The font menu 228
5.5 Designing your own fonts 234
5.5.1 Reading the font generator 236
5.5.2 Big text: enlarging text 240
5.5.3 A fixed width font generator 243
5.5.4 A proportional font 252
Page v
----------------------------------------------------------------------------
6. Graphic Hardcopy 259
6.1 A simple hardcopy routine 262
6.2 Hardcopies: enlarging and shrinking 265
6.3 Printing selected windows 268
6.4 ScreenDump - the complete screen 271
6.5 Multitasking hardcopy 274
7. The IFF-ILBM standard 279
8. A 1024*1024 Paint program 293
8.1 Paint-1024 program instructions 311
9. Graphic programming in C. 315
9.1 The Amiga libraries 316
9.2 The boss: The view 317
9.3 The foreman: ViewPort 317
9.4 The worker: Bit-Map 319
9.5 The messenger: Rasinfo 322
9.6 The laborer: RastPort 323
9.7 Finish the day: 325
10. Lines and pixels 327
10.1 Pixels set with Writepixel 327
10.2 Drawing lines with move and draw 332
11. Colour: Drawing pens 339
11.1 The Drawmodes 340
11.2 The foreground pen 341
11.3 The background pen 341
12. Intuition and graphics 343
12.1 The individual screen 344
12.2 The Window 345
12.3 Exiting Intuition 345
13. Filling areas in C. 347
13.1 A flood function 347
13.2 Filling rectangles 349
13.3 Polygon filling: Area, makes it possible 356
14. The Colormap functions 381
14.1 Setting a new colour palette 382
14.2 Changing one colour 382
14.3 Available colours 383
14.4 The pixels colour 386
PAGE vi
----------------------------------------------------------------------------
15. Text output 387
15.1 The text length 389
15.2 Fonts with the Amiga 389
15.3 Opening fonts 390
15.4 Closing the font 391
15.5 Software controlled text styles 392
15.6 Fonts a la carte 393
16. The Blitter functions 399
16.1 Clearing a memory area 399
16.2 Copying data with the Blitter 400
16.2.1 The ClipBit function 402
16.3 Reading data with the Blitter 407
17. Amiga resolution modes 413
17.1 The resolution modes 414
17.2 The color modes 418
17.2.1 The EXTRA_HALFBRITE mode 418
17.3 The special modes 422
17.3.1 Dual Playfield 422
17.3.2 Double buffering 423
17.4 Other modes 435
17.4.1 VP_HIDE 435
17.4.2 Sprites 435
17.4.2.1 The hardware sprites 435
17.4.2.2 Hardware sprites in 15 colours 439
17.4.2.3 Sprite collisions 440
18. The Amiga animation system 451
18.1 Vsprites 451
18.1.1 Vsprites and collisions 455
18.2 Another GEL: the bob 465
18.2.1 Bobs in buffered bit-maps 476
18.3 AnimObs and AnimComps 479
18.3.1 Collisions with AnimObs 484
19. Copper programming in C 495
Appendices:
A: Structure and include files 503
B: The library-functions 527
C: The hardware 557
Index 593
page vii
----------------------------------------------------------------------------
INTRODUCTION
The graphics powers of the Amiga are fantastic. You have probably seen many
examples of Amiga graphics that overwhelm competing computers. How can you
take command of this wonderful machine? How do you create your own graphics
programs and understand what is going on inside your Amiga?.
The answers to these and hundreds of other questions are in this book. We
will present the material so that it will interesting for both beginners
and experienced programmers.
In chapter 1 we gently introduce the beginner to the amazing graphic world
of the Amiga. Here you will learn first hand how to create graphics.
Heavily documented BASIC programs demonstrate the use of the BASIC graphic
statements and how to design and use moveable objects etc..
Experienced programmers will find chapters 2 thru 8 a step by step of the
Amiga's multitasking graphics envoironment. We'll introduce you to the
multitude of system graphic routines in the Kickstart-ROM. We discuss in
detail, with tables, all data structures (window, screen, Viewport and
more) At the end of this section you will be able to use graphics in 64
color, halfbrite or 4096 HAM mode. You will also be capable of programming
a coprocessor and other tasks that were not thought possible in BASIC.
In chapters 9 thru 19, we will examine the use of windows and screens using
the C language, unveiling many system secrets. Last we enter the exiting
world of automated animation, bobs, sprites and our own virtual sprite
machine. Much of the information covered in this section is not even in the
ROM manuals from Commodore!
Whether you use this book as an introduction to graphics or for solving a
particular problem, you will find the contents of this book to be a wealth
of grpahics information.
Weltner, Trapp, Jenrich (The authors)
Razor Blade, Chaos, Mit, Viper, Shadowfax, Alchemist (The pirates!).
PAGE ix
----------------------------------------------------------------------------
CHAPTER 1 - AMIGA GRAPHICS.
In many ways the Amiga is a very unusual computer. Its excellent features
have convinced not only graphics users, but many others that it is the
computer for them.
The Amiga repeatedly surprises and fascinated users by the speed of its
graphics, even graphics done in BASIC. Whether your graphics are very
complex or only a small part of your BASIC program, there are several easy
statements for drawing pixels, lines and circles.
A major difference between the Amiga and other computers is that you
display text and Hi-resolution graphics on the same screen. The means that
you can easily mix text and graphics without opening another screen. You
can start experimenting with the graphic statements immediately.
-----------------------------------------------
1.1 SETTING PIXELS WITH PSET.
The smallest unit in graphics is the PIXEL. We create all computer graphics
from a full screen to single lines and pixels, by joining many small screen
pixels. The statement you use to set pixels is short and simple:
pset(10,20)
This example sets a pixel at a point 11 (10+1) from the left and 21 (20+1)
down from the top of the window. Please note that pixel addressing, when
referring to screen positions, starts with the value zero (0) and not one
(1).
--------------------------------
1.1.1 USING THE MOUSE AND PSET: A SIMPLE DRAWING BOARD.
Using the statement PSET you can set any desired point within the limits of
the specified output window. The following program is a good example of
this. Each time you click the left mouse button you will set a pixel on the
screen where the point of the mouse pointer is located ( a pixel at the
tip of the pointer).
PAGE 1
----------------------------------------------------------------------------
This is a very primitive drawing program, but we will use this principle to
create a complete paint program.
REM 1.1.1 Drawing with the mouse.
PRINT "Now you can draw with the mouse"
WHILE INKEY$ = ""
IF MOUSE(0) <> 0 THEN
X = MOUSE(1)
Y = MOUSE(2)
PSET(X,Y)
END IF
WEND
As you can see, you need very few program lines for this small drawing
program. The MOUSE function provides control of the mouse. When you click
the left mouse button MOUSE(0) is not equal to zero. Now we can determine
the mouse co-ordinates using MOUSE(1) for the X position and MOUSE(2) for
the Y position.
-----------------------------------
1.1.2 ROSETTE AND GARLAND PATTERNS.
You can create beautiful graphics using only the PSET statement. As you
have just seen, you can draw them yourself, or you can let the computer
create them for you. To have the computer generate you graphics you have to
construct your statements so that the computer will understand what you
want. To do this, you put your ideas into mathematical formulas. The
following program generates different rosette patterns on the screen using
formulas.
REM 1.1.2 Rosette
pi=3.1415296#
f = .5 ' specifies the relation of height and width
INPUT "How many edges : ",edges
CLS
IF edges <> - 1 THEN edges = edges + 1
REM predetermined values
radius = 100 ' Radius of maximum circle
inside = 3 ' Count of "inside" lines
outside = 3 ' Count of "outside" lines
FOR t = -inside/10 TO outside/10 STEP .1
FOR angle = 0 to 2*pi STEP .01
x = radius * COS(angle)+t*radius*COS(angle*edges)
y = radius * SIN(angle)+t*radius*SIN(angle*edges)
PSET(300+x,y*f+100)
NEXT angle
NEXT t
PAGE 2
----------------------------------------------------------------------------
You can determine the shape of the rosette by entering different values for
edges. Values between two and twenty work best, however negative numbers
will also generate quite interesting images.
You can also modify the figures you created by experimenting with the
program variables.
What you eventually see on screen is a design formed by many ellipsoids
that are connected together. Ellipsoid simply means a series of curves
generated by rolling an ellipse around one of its axis points. We do not
draw the ellipse itself, only the outermost path of the curve. You can see
this path as we plot it on the screen. The complete ellipsoidal formula can
be found in any mathematics reference guide. We have changed it slightly to
make it more user friendly.
------------------------------
1.1.3 ERASING PIXELS.
Since you can set the pixels, you must be able to erase them. In AmigaBASIC
this procedure is very similar to setting the pixels, in fact the statement
sounds almost the same. This statement has the same syntax as PSET and is:
PRESET (x,y)
As you can see the only difference between the two statements is two
letters. In a program it looks like this:
REM 1.1.2 Demo for PRESET
a = 200
b = 400
c = 1
loop:
FOR x=a TO b STEP c
PSET(x,100)
PRESET(x-40*c,100)
NEXT x
SWAP a,b
c = -c
GOTO loop
In this program a 40 pixels long line appears to be moving back and forth
on the screen. What exactly happens is that we add a new pixel to the
beginning of the line and erase one from the end. To exit the program,
press and hold the <CONTROL> key, then press the <C> key.
PAGE 3
----------------------------------------------------------------------------
1.1.4 ADDING COLOUR TO YOUR SCREEN.
The previous programs have not really been a challenge for the Amiga. We
could easily transfer these programs to other computers, although this does
not apply to all programs. For example, when it comes to the use of colors,
the amiga is unique. There are very few computers that can clain a palette
of 4096 colours. We will begin by showing you how to use a 32 colour
palette and later advance to 64 and even 4096 colours. You can set coloured
pixels in the same way you previously set pixels, with the PSET statement.
The only difference is that you must add, at the end of the statement, the
value of the colour for a colour register:
PSET(10,20),2
In this example, we determine the colour of the pixel from the second
colour register. The default colour always starts with black so this pixel
will be black.
If you now attempted to access the other 32 color registers (numbered 0 -
31) you would have problems. By the fifth or higher register value, the
computer would display an error message. Why? Because we do not use all 32
colours for every screen, the Amiga automatically saves memory by not
assigning memory for these colours. The more colours you use, the more
memory you requires (more on this later).
First, we have to open a new screen (one that exists at the same time as
the workbench screen and is either behind it or covered by it). When you
open a new screen you can specify parameters such as width, height, mode
and colour depth. For depth you can use values between 1 and 5, certain
screen modes only allow a maximum of 4. The following formula calculates
the number of colours: 2 to the power of depth (2**depth). When you select
a mode, you set the resolution of the screen. There are four possible
modes on NTSC video systems:
MODES RESOLUTION
----- ----------
1 320*200
2 640*200
3 320*400
4 640*400
PAL systems, available in Europe, contain 256 screen lines. In most of our
programs we use mode one. Please note that the width and height of the
screen cannot be greater than the values of the resolution mode selected.
PAGE 4
----------------------------------------------------------------------------
Nothing can be sent directly to a screen. Once we open a screen we must
also open a window for it. This window is where all text and graphics will
appear.
REM 1.1.4A 32-color DEMO
REM open a screen
SCREEN 1,320,200,5,1
REM open a window
WINDOW 2,"Colourpot",(0,0)-(311,185),16,1
FOR y = 0 TO 186
FOR x = 0 TO 311
PSET (x,y),(x+y) MOD 32
NEXT x
NEXT y
WHILE INKEY$ = "": WEND
REM close window first, then screen
WINDOW CLOSE 2
SCREEN CLOSE 1
On the screen you will see all 32 possible colours. At the end of the
program we close the window and screen, since they are no longer required.
We can also display some interesting patterns using the colour demo. For
example:
REM 1.1.4B Colour Demo
SCREEN 1,320,200,5,1
WINDOW 2,"ColorDemo",(0,0)-(62,62),16,1
FOR m = 0 TO 31
FOR x = -m TO m
FOR y = -m to m
PSET (31+x,31+y),((ABS(x) AND ABS(y))+32-m) MOD 32
NEXT y
NEXT x
NEXT m
WHILE INKEY$="":WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
OR:
REM 1.1.4C Pyramid
SCREEN 1,320,200,5,1
WINDOW 2,,(0,0)-(20,10),16,1
FOR y = 0 TO 19
FOR x = 0 TO 19
f1 = ABS(x-10)
f2 = ABS(y-10)
IF f1<f2 THEN SWAP f1,f2
PSET(x,y),31-f1
NEXT x
NEXT y
WHILE INKEY$ = "": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
PAGE 5
----------------------------------------------------------------------------
These two programs demonstrate different methods of colour manipulation. In
the first program we joined the X and Y values using AND. You can also
create nice patterns by multiplying the values or by using XOR.
In the second program, we drew a square that had a dark outer edge and
became progressively lighter towards the centre. It creates the effect of
looking at a pyramid from the top. To do this, we used only colour
registers 21 thru 31. These registers contain varying levels of grey shades
useful in generating 3-D effects.
--------------------------------
1.1.5 MORE ABOUT PSET AND PRESET.
We mentioned previously that PRESET erases the pixels that PSET set. This
is only true as long as you do not specify a colour value with PRESET:
PSET(100,100)
PRESET(100,100)
The above example demonstrates what we mean. We set a pixel and then erase
it.
The example below has a completely different action, the pixel is drawn in
white and not erased:
PSET(100,100),1
PRESET(100,100),1
The moment you specify a colour register both statements will have the same
result. It becomes a matter of personal preference which statement you use.
An alternative method to using PRESET(x,y) to erase pixels is to use
PRESET(x,y),0. Why are there two statements which seem to do the same
thing? The default colour ( the colour used if you do not specify a colour
value with PSET and PRESET) is the key difference. With PSET the default
colour is the foreground colour and with PRESET it is the background
colour. This also has an effect on changes to the foreground and background
colours. You do not have to concern yourself with these values when using
PSET to erase pixels.
PAGE 6
----------------------------------------------------------------------------
Using both statements in a program makes it much easier to understand what
is going on. You can see right away where pixels are being drawn or erased.
REM 1.1.5 Demo for P(RE)SET
RANDOMIZE TIMER
SCREEN 1,320,200,5,1
WINDOW 2,,(0,0)-(311,185),16,1
l=.8
DIM y(l*100)
WHILE INKEY$ = ""
COLOR INT(RND*32),INT(RND*32)
CLS
FOR j = 1 TO 4
y(j) = 50+RND*80: s(j) = RND*50
NEXT j
FOR x = 0 TO 6.2+l STEP .04
FOR j = 1 TO 4 STEP 2
PRESET((x-1)*50,y(j)-s(j)*SIN(x-1))
PRESET((x-1)*50,y(j+1)-s(j+1)*COS((x-1)*j))
PSET(x*50,y(j)-s(j)*SIN(x)),INT(RND*32)
PSET(x*50,y(j+1)-s(j+1)*COS(x*j))
NEXT j
NEXT x
WEND
WINDOW CLOSE 2
WINDOW CLOSE 1
In this program, lines of different lengths move across the screen. As in
the first PRESET demo program, we set a pixel at the front of a line and
erase one at the end. What is special about this program is the changing of
the foreground and background colours. As you can see, erasing using PRESET
is quite easy.
-----------------------------
1.1.6 THE "OPPOSITE" OF PSET: THE POINT STATEMENT.
By opposite we mean instead of setting a pixel we can read a pixel to see
if it is set and what colour it is. To do this we use the POINT statement:
PRINT POINT(x,y)
The result will either be the colour or a value indicating that the pixel
(x,y) coordinates are not in the output window. In the first case, the
number of colour register is printed, in the second a value of -1 is
returned.
PAGE 7
----------------------------------------------------------------------------
Our next program creates a few graphic lines, then the POINT statement is
used to determine if a pixel has been set. The resulting picture will look
as if it was created by using randomly set pixels.
REM 1.1.6 Patterns
SCREEN 1,320,200,5,1
WINDOW 2,,(0-0)-(80,80),16,1
RANDOMIZE TIMER
x=40
y=40
Direction:
dx = INT(RND*5)-2
dy = INT(RND*5)-2
IF dx = 0 AND dy = 0 THEN Direction
IF ABS(dx) > ABS(dy) THEN
st = ABS(dx)
ELSE
st = ABS(dy)
END IF
WHILE INKEY$ = ""
IF POINT (x+dx, y+dy)=-1 THEN Direction
FOR i = 1 TO st
x = x+dx/st
y = y+dy/st
PSET (x,y),POINT(x,y) MOD 31+1
NEXT i
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
The arrangement used to build this screen is quite simple. One pixel
wanders around the screen. (With each move we check the pixels positions
colour register and increment it by one.) When the moving pixel hits a
window border we change directions.
End the program by pressing any key.
---------------------------------------------
1.1.7 RELATIVE ADDRESSING.
With PSET, and almost all other graphics statements in AmigaBASIC, there
are two modes of addressing. We can easily compare the firt method to home
addresses and postcodes. When you send a letter it always arrives at the
address to which you send it (BULLSHIT!!!!). This is the method of
addressing we have been using in our programs:
PSET (20,30)
PAGE 8
----------------------------------------------------------------------------
The values 20 and 30 are the absolute coordinates of the pixel we want to
set in its row and column. This method of addressing is named "absolute".
The second method of addressing is called "relative". Relative address
coordinates do not refer directly to a row and column position, instead
they point to a position relative to your current position. This is like
telling the computer: from your current position move three pixels to the
right and then two down. The key to this method is the current position of
the graphic cursor. The indicator for relative addressing is the word STEP
which is positioned before the parenthesis:
PSET STEP (3,2)
Although we cannot ask where the graphics cursor is, we can move it easily
without doing any drawing:
v = POINT(x,y)
We move the graphics cursor automatically when we set or erase points. By
using this form of the POINT statement, we can relocate it anywhere we
want. The variable 'v' can be any variable not already used in your
program.
When you start a program the graphic cursor will always be in the centre of
the output window.
If you use relative addressing with constant coordinates, you plot pixels
with the same offset between them. This is not something you would
necessarily want, but our next sample program demonstrates how this works.
This program is very similar to our first drawing program but instead of
setting one pixel when you press a mouse button it will set several pixels
giving a brush effect.
REM 1.1.7 Relative Addressing.
WHILE INKEY$ = ""
IF MOUSE(0) <>0 THEN
x = MOUSE(1)
y = MOUSE(2)
PSET (x,y)
PSET STEP (10,10)
PSET STEP (10,-10)
PSET STEP (-10,-10)
PSET STEP (10,0)
END IF
WEND
The first pixel we set using an absolute address. The other four pixels we
set with a relative address, which made the distance between them the same.
PAGE 9
----------------------------------------------------------------------------
1.2 THE LINE STATEMENT.
The LINE statement has two uses that look similar, but produce completely
different results. First, as the name implies, you can draw striaght lines.
You can also use LINE to draw boxes. We will discuss the second form of the
LINE statement in more detail later on.
LINE (20,10)-(200,100),2
The above statement draws a black (colour register 2) line from point
(20,10) to point (200,100).
------------------------------------------
1.2.1 THE POWER OF LINE.
With the PSET statement, you can perform almost anything that is possible
in the computer graphics world. You can create any desired graphics or
lines you want. The problem with using PSET by itself is the time involved.
The time saved using the LINE statement is enormous and easily
demonstrated:
REM 1.2.1 Benchmark for PSET with LINE.
REM straight line with PSET
FOR i = 0 TO 80
PSET(i,i)
NEXT i
REM straight line with line
LINE (180,0)-(0,180)
The LINE statement opens up more possibilities, probably a lot more than
the PSET statement. In the same way you form lines by setting pixels one
after another, you can draw a line simply by specifying the start and end.
In this example, the start and end coordinates for the LINE statement were
in the same row.
----------------------------------------------
1.2.2 THE MOIRE EFFECT.
Moire patterns become visible whenever you draw lines close to or
intersecting each other. Using this effect you can design astounding
pictures. Watch the graphics created by the program below.
PAGE 10
----------------------------------------------------------------------------
REM moire-Lattice.
a=182 'size of rectangle '
FOR s = 1 TO 10
CLS
FOR i = 0 TO a STEP s
LINE (140,1)-(140+2*a,i),2
LINE (140,1)-(140+2*i,a),2
LINE (140+2*a,a)-(140,i),2
LINE (140+2*a,a)-(140+2*i,1),2
NEXT i
WHILE INKEY$="": WEND
NEXT s
We draw lines from two corners of the rectangle to the opposite side. The
Moire effect shows up at the connecting points of both corners because that
is where we have drawn most of the lines.
We can also achieve this effect by drawing many lines from a single point
and increase the effect by alternating between two different colors.
REM 1.2.2B Moire Demo 2.
xmax = 618 ' size of output window
ymax = 186
COLOR 1,2 'background black
Start:
CLS
xm = INT(RND*xmax) 'Coordinates of Centre Point
ym = INT(RND*ymax)
FOR i = 0 TO ymax
LINE (xm,ym)-(0,i),i MOD 2+1
LINE (xm,ym)-(xmax,i),i MOD 2+1
NEXT i
FOR i = 0 TO xmax
LINE (xm,ym)-(i,0),i MOD 2+1
LINE (xm,ym)-(i,ymax),i MOD 2+1
NEXT i
WHILE INKEY$ = "": WEND
GOTO Start
When you observe the graphics created by this program, it is hard to
believe we created them so easily.
------------------------------------------
1.2.3 QUIX, LINE GALORE.
Again, we come back to the speed of the line statement. In the following
program, we let quix race around the screen. Quix is composed of many lines
that are more or less parallel. The movement of quix is caused by erasing
lines at one end and drawing them at the opposite end. It becomes difficult
to tell where a line starts or ends,since the portion added uses the same
end coordinates as the line it is being added to. We simply modify the
coordinates slightly to make the existing line longer.
PAGE 11
----------------------------------------------------------------------------
REM 1.2.3 Quix.
DEFINT a-z
SCREEN 1,320,200,5,1
WINDOW 2,"QUIX",(0,0)-(297,185),31,1
RANDOMIZE TIMER
a=20
DIM x(1,a),y(1,a)
x(0,0)=150
y(0,0)=150
x(1,0)=170
y(1,0)=100
WHILE INKEY$ = ""
FOR z = 0 TO a
LINE (x(0,z),y(0,z))-(x(1,z),y(1,z)),0
FOR i = 0 TO 1
newx: x(i,z)=ABS(x(i,alt)+RND*20-10)
IF x(i,z)>WINDOW(2) THEN newx
newy: y(i,z)=ABS(y(i,alt)+RND*20-10)
IF y(i,z)>WINDOW(3) THEN newy
NEXT i
f1 = f1 MOD 31 + 1
LINE (x(0,z),y(0,z))-(x(1,z),y(1,z)),f1
alt = z
NEXT z
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
While quix is moving around you can stop it by clicking and holding on the
window size gadget and shrinking the window. The coordinates used by quix
will never be greater than the current window size. You can determine the
actual size of the output window by using WINDOW(2) (width) and WINDOW(3)
heigth.
---------------------------------------------
1.2.4 FUNCTION PLOTTER.
A function plotter is one of many practical mathematical applications
requiring graphics. It can be a great help in the visual examination of
functions. Experimenting with parameters and functions can also be a lot of
fun while looking for interesting curves. THe function plotter is very
comprehensive and user friendly. For example, the program will compute your
coordinates so that the function plotted will always be within the window
limits.
PAGE 12
----------------------------------------------------------------------------
REM 1.2.4 FUNCTION PLOTTER.
DEFDBL x,y,m,f
DIM y(618) ' Maximum number of function values.
x1 = -10: x2=10 ' value limits.
func = 1 ' First function.
coordinates=1 ' Coordinates intersect at.
MENU 1,0,1,"Activity "
MENU 1,1,1,"Draw Function "
MENU 1,2,1,"Enter coordinates "
MENU 1,3,1,"Crosshairs off "
MENU 1,4,1,"Quit "
MENU ON
MENU 2,0,1,"Function "
DEF FNy1(x) = SIN(x)/(x^2+1)
a$(1)="y=sin(x)/(x^2+1) "
MENU 2,1,1,a$(1)
DEF FNy2(x) = SIN(x)*10-1/x+x^2
a$(2)="y=sin(x)*10-1/x+x^2"
MENU 2,2,1,a$(2)
DEF FNy3(x) = SIN(1/x)/x
a$(3)="y=sin(1/x)/x "
MENU 2,3,1,a$(3)
DEF FNy4(x)=(EXP(x)-1)/(EXP(x)+1)
a$(4)="y=(e^x-1)/(c^x+1) "
MENU 2,4,1,a$(4)
WINDOW 1, a$(1),,23
GOSUB Calculate
Select: SLEEP
ON MENU GOSUB Branch
GOTO Select
Selection: ON MENU(1) GOSUB Calculate, Entry, Crosshair, Quit
RETURN
Branch: ON MENU(0) GOTO Selection
func = MENU(1)
WINDOW 1,a$(func)
Entry: WINDOW 2,"Coordinate Entry",(0,0)-(250,9),16
INPUT "Start Value : ";x1
INPUT "End Value : ";x2
IF x2<x1 THEN SWAP x1,x2
WINDOW CLOSE 2
Calculate: IF x1=x2 THEN Entry
fwidth = WINDOW(2)
WINDOW 2,"Calculating function - wait",(0,0)-(300,0),0
min = 0
max = 0
ON ERROR GOTO Errorcond
FOR i = 0 TO fwidth
fvalue = x1+(x2-x1)*i/fwidth
ON func GOSOB F1,F2,F3,F4
PAGE 13
----------------------------------------------------------------------------
IF y(min)>y(i) THEN min = i
IF y(max)<y(i) OR y(max) = 9999 THEN max = i
Proceed: NEXT i
ON ERROR GOTO 0
min=y(min)
max=y(max)
WINDOW CLOSE 2
GOSUB Title
Drawplot: CLS
fheight = WINDOW(3)-8
IF coordinates=1 THEN
IF min<=0 AND max >=0 THEN
h=fheight+min*fheight/(max-min)
LINE(0,h)-(fwidth,h),2
END IF
IF x1<0 and x2>0 THEN
b=-x1*fwidth/(x2-x1)
LINE(b,0)-(b,fheight),2
END IF
END IF
IF min=max THEN 'When min=max then draw striaght line
IF max=9999 THEN ' Funtion value not defined
CLS
ELSE
LINE(0,fheight/2)-(fwidth,fheight/2)
END IF
END IF
j=0
WHILE (y(j)=9999 AND j<618) ' find first defined
function value'
j=j+1
WEND
IF j=618 THEN RETURN
PSET (j,fheight-(y(j)-min)*fheight/(max-min)
FOR i=j+1 TO fwidth
IF y(i)<>9999 THEN
IF flag THEN
PSET(i,fheight-(y(i)-min)*fheight/(max-min))
flag=0
ELSE
LINE (i,fheight-(y(i)-min)*fheight/(max-min))
END IF
ELSE
flag = 1
END IF
NEXT i
RETURN
Errorcond: y(i) = 9999
RESUME Proceed
F1: y(i) = FNy1(fvalue)
RETURN
PAGE 14
----------------------------------------------------------------------------
F2: y(i) = FNy2(fvalue)
RETURN
F3: y(i) = FNy3(fvalue)
RETURN
F4: y(i) = FNy4(fvalue)
RETURN
Title: MENU 3,0,1,MID$(STR$(x1),1,5)+
"<x<"+MID$(STR$(x2),1,5)
MENU 4,0,1,MID$(STR$(min),1,5)+
"<y<"+MID$(STR$(max),1,5)
RETURN
Crosshair: IF coordinates = 1 THEN
coordinates = 0
MENU 1,3,1,"Crosshairs ON "
ELSE
coordinates = 1
MENU 1,3,1,"Crosshairs OFF "
END IF
GOTO Drawplot
Quit: WINDOW 1,"Function Plotter",(0,0)-(617,184),31
MENU RESET
END
You are probably asking yourself what does a function plotter have to do
with the LINE statement since we form a function by plotting points. Our
program works by plotting a point for each curve. Between these points are
large gaps and if we only plotted the calculated points our function would
not look like a curve. We make the connection between all of these points
by using the LINE statement.
------------------------------------------
1.2.4.1 FUNCTION PLOTTER MODES AND MENU CONTROLS.
This program has two standard and two pseudo menus. The pseudo menus have
no sub-menus and only provide you with information. The first pseudo menu
displays the limit values of the curve in the X direction. The second
pseudo menu lists the maximum and minimum Y values of the function. Both of
these menus are only visible after your funcion has been plotted and
changed with each function.
The activity menu has four sub-menus. Sub menus one redraws the current
function and is used after you have changed the size of the output window.
The other three menus are for entering new coordinates, making the
crosshair visible and invisible and exiting the program. With the second
menu you can choose from one of four PRESET mathematical functions.
Unfortunately with BASIC it is not possible for you to input the function
formulas. If you want to test other functions, you can do so by changing
those at the beginning of the program. You will also have to change the
text for the a$(n) since it lists the function for menu 2.
PAGE 15
----------------------------------------------------------------------------
1.2.4.2 UNDEFINED FUNCTION VALUES.
This program allows you to view mathematical functionson your screen
without spending a lot of time figuring out values. For example, lets say
you want to compute the value of a curve 1/x and you input a value of x =
0. Since division by zero creates an error and we used the ON-ERROR-GOTO
assignment before calculating the function values, BASIC branches on the
error. Simply put, instead of the program halting on the error it goes to a
specified error handler routine which processes the problem.
In this program, the function value on specific errors will default to
9999. If the drawing routine receives this value, it then knows the pixel
should not be plotted.
In addition to division by zero, overflow errors are also handled. There
is, of course, the danger of other unforseen errors happening at which time
the program will stop.
For the program to properly interpret errors that occur after the function
calculations, the ON-ERROR-GOTO assignment is switched off again.
--------------------------------------------
1.2.4.3 SCALING.
You can directly affect the size and shape of a curve by enlarging or
shrinking it. When you change the size of the output window there is a
proportional effect on the displayed curve by either stretching or
compressing it.
By scaling we mean that a curve is always displayed to fill the entire
window. However, the values of the X and Y axis are dependent on the height
and width of the window. Stertching a curve can sometimes produce confusing
results. On the other hand, compressing it can cause a smooth straight
curve to appear more sloped.
The advantage to this method of presentation is that you do not have to
worry much about the course of the curves. As mentioned previously, you can
obtain more information about a curve from the menus.
PAGE 16
----------------------------------------------------------------------------
1.2.5 DRAWING RECTANGLES.
Earlier we discussed the LINE statement not only to draw lines, but also
rectangles. Now we will show you how to draw a rectangle with a single LINE
statement. The difference between lines and rectangles is a B, at the end
of the statement.
LINE (20,10)-(200,100),2,B
This statement draws an unfilled black rectangle on the screen. The first
coordinate opair is the upper left hand corner and the second pair is the
lower right hand corner. You can see it is very easy to draw rectangles.
Althought the sides will always be parallel to the output window, this type
of rectangle is very useful.
You can also draw filled rectangles instead if unfilled by using ,BF
instead of ,B at the end of the statement.
LINE (30,10)-(300,100),2,BF
If you leave out the color parameter the rectangle is drawn in the
foreground colour.
With this statement we can also perform a speed test. Our test program is
similar to the boxes demo of the workbench. We will draw filled rectangles
with random coordinates and colours.
REM 1.2.5 Speed test of
REM the LINE statement
WHILE INKEY$ = ""
x = WINDOW(2)
Y = WINDOW(3)
LINE (RND*x,RND*y)-(RND*x,RND*y),INT(RND*4),BF
WEND
Even though this is a very simple program, it seems amazing if you are not
familiar with the Amiga. The speed with which the Amiga draws and fills
rectangles is very fast, so fast in fact that you do not have time to count
them. Keep in mind that these are not all small rectangles. Some of them
have thoiusands of pixels and you still cannot see the difference.
PAGE 17
----------------------------------------------------------------------------
1.2.6 RELATIVE ADDRESSING WITH THE LINE STATEMENT.
You can use relative co-ordinates with the LINE statement in either mode in
exactly the same way as you used them with PSET.
The first coordinate pair is relative to the graphic cursor position and
the second pair is relative to the starting point of the line.
Both coordinates do not have to be relative. The following statement draws
a line from (30,20) to (20,120)
LINE (30,20)- STEP(-10,100)
If you want to continue drawing from the current position of the graphic
cursor, you just leave the first coordinate pair out. We will demostrate
this method in the following program in which we will draw multiple
rectangles inside of each other:
REM 1.2.6A Boxes within Boxes.
SCREEN 1,320,200,2,1
WINDOW 2,"Rotated Rectangle",(0,0)-(311,185),16,1
COLOR 2,1
CLS
d=5 'Distance (1-10)
b=60 'Width of first box.
FOR x = 0 TO 311 STEP b
FOR y = 0 TO 185 STEP b
x1=x: x2=x+b
y1=y: y2=y
FOR a = 0 TO .7 STEP ATN(d/b) 'a<pi/4
IF((x+y)/b)MOD 2 = 0 THEN 'rotate direction
LINE (x1,y1)-(x2,y2)
LINE -(2*x+b-x1,2*y+b-y1)
LINE -(2*x+b-x2,2*y+b-y2)
LINE -(x1,y1)
ELSE
LINE (2*x+b-x1,y1)-(2*x+b-x2,y2)
LINE -(x1,2*y+b-y1)
LINE -(x2,2*y+b-y2)
LINE -(2*x+b-x1,y1)
END IF
x1=x1+COS(a)*d 'calculate next rectangle
x2=x2-SIN(a)*d
y1=y1+SIN(a)*d
y2=y2+COS(a)*d
NEXT a
NEXT y
NEXT x
WHILE INKEY$="": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
PAGE 18
----------------------------------------------------------------------------
When the program is finished you can hardly distinguish the individual
rectangles. They have dissappeared in the overall pattern. This effect is
increased by neighboring rectangles being rotated in the opposite
direction.
Both coordinates pairs are required for only the first line of a rectangle
or another geomertric figure.
The second coordinate pair of the LINE statement determines where the
graphic cursor will be after drawing the line. If you plan ahead you can
save yourself some work: Using LINE to draw boxes, you can swap the X and Y
coordinates and determine what corner the graphic cursor will be after the
statement. This is very useful when using relative addressing.
The following program draws a random bar graph of the type popular for
statistics. Our bar graph is to be three dimensional so we have created a
shadow composed of line.
REM 1.2.6B Bar Graph
RANDOMIZE TIMER
SCREEN 1,320,200,4,1
WINDOW 2,"Bargraph",,31,1
FOR i = 0 TO 7
x = 30+i*37
y = INT(RND*160)+1
LINE (x,180-y)-STEP(6,-6),i+1
LINE -STEP (0,y),i+1
LINE -STEP (-6,6),i+1
LINE -STEP (-20,-y),i+1,BF
LINE -STEP (6,-6),i+1
LINE -STEP (20,0),i+1
NEXT i
WHILE INKEY$="": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
Except for the first coordinate pair of each bar all coordinates are
relative, including those of the boxes. Using this method can save you some
time because you have to calculate only a few coordinates.
PAGE 19
-----------------------------------------------------------------------------
1.3 THE CIRCLE STATEMENT.
For a computer that is designed to handle professional graphics we would
expect BASIC to include a 'circle' statement.
In school you learned that you require a center and a radius to draw a
circle. This is the same for AmigaBASIC.
CIRCLE (200,100),100
We can draw coloured circles in the same way. The value for the colour
register is simply added at the end of the statement:
CIRCLE (200,100),100,2
With both circles there are two notable points:
1.) Both figures are more ellipse shaped than round.
2.) The radius is smaller than the height in pixels of the window, but with
a radius of 100 the circle should not fit in the window.
Both points are dependant upon each other and upon the aspect ratio.
-----------------------------------------
1.3.1 THE ASPECT RATIO.
You have probably experimented with the adjustments on the back of your
monitor. One of these adjustments changes the vertical height of your screen.
Using this adjustment you could expand your screen vertically until our
last circle appeared round. The problem with doing this is that you would cut
off the top and bottom of the screen. If you changed to a different screen
resolution you circle would be egg-shaped.
We have a much better solution. You can use a parameter with the CIRCLE
statement the adjusts the pixel height and width ratios to round the image.
This is how you do it:
CIRCLE (100,100),100,,,,2
There are four commas between the radius and the aspect ratio because we
have left ut 3 parameters: the colour, which we already selected and two
angle parameters that we will discuss later.
PAGE 20
----------------------------------------------------------------------------
Drawing perfect circles is not the only way that you can use the aspect
ratio. In our next program, which draws many ellipses and circles, you
can create your own shapes. The shapes we achieve with this program range
from circles to diamonds to four pointed stars. All of these figures are
created using many arcs:
REM 1.2.1 Ellipses
SCREEN 1,320,200,2,1
WINDOW 2,,(0,0)-(311,185),16,1
FOR g = 0 TO 80 STEP 5
CLS
FOR f = .0001 TO 1 STEP .1
CIRCLE(100,100),(80-g*f),,,,f
CIRCLE(100,100),(80-g*f),,,,1/f
NEXT f
WHILE INKEY$ = "": WEND
NEXT g
WINDOW CLOSE 2
SCREEN CLOSE 1
We have used the lower resolution of 320*200 for this program because the
aspect ratio is equal to one. This is the reason the horizontal and
vertical allipses are so similar. The difference is that once we use an
aspect ratio of F which is smaller than 1 and the second time we use 1/F
which is larger than one. Thus the ellipses are basically the same, except
one is tall and the other is wide.
All of the figures are dependant on the values of the aspect ratio and the
radius. The larger we make the value of F, the rounder the circle and, at the
same time, the smaller the radius. How small the radiius becomes is
different for each figure.
------------------------------------------------
1.3.1.1 ANIMATION USING CIRCLE
The next program contains simple animated graphics. It simulates a bouncing
ball on the screen. With each bounce the ball will compress slightly as if
made of rubber. This action gives it the next bounce.
REM 1.3.1.1A Springing Ball.
SCREEN 1,320,200,2,1
WINDOW 2,,(0,0)-(100,100),16,1
WHILE INKEY$=""
FOR i = 0 TO 3.14 STEP .08
f=1
y=70*SIN(i)
IF y<10 THEN f=.5+y/20
CLS
CIRCLE (50,100-y),20,1,,,f
NEXT
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
PAGE 21
----------------------------------------------------------------------------
The aspect ratio is dependant on the height of the ball which we calculate
with the sine function. When the ball is lower than the radius of the
circle, we change the value of f (aspect ratio) and the ball compresses.
The principle of our animation is simple: We draw a circle and calculate
the position of the next circle. Before we draw the next circle we clear the
screen. Because you dont have to calculate the circle, it is simpler and
faster to clear the screen instead of erasing the existing circle with
the background colour. When we use CLS, the blitter, a special graphic
co-processor, takes care of most of the work. Clearing the screen is a
small task for the blitter, which can fill areas of up to a millions
pixels in a second.
In the next program, we show you a wire model of a chess piece. When you
press a key the figure will rotate. You might recognise this figure
immediately: its the queen.
The moire effect, which you saw with the LINE statement, also appears with
the CIRCLE statement. It will always appear when many lines, or curves in
this case, are close together.
REM 1.3.1.1.B CHESS PIECE
FOR f=0 T0 .5 STEP .05
CLS
READ l
FOR i = 1 TO l
READ a
CIRCLE (320,150-i*3*2*(.f-5)),a*2,2,,,f
NEXT i
RESTORE
WHILE INKEY$="": WEND
NEXT f
REM Queen
DATA 39,31,29,29,31,26,23
DATA 21,27,22,19,16
DATA 14,13,13,12,12,12,11,11,11,11,22
DATA 16,16,20,16,16
DATA 17,18,19,21,23,26,29
DATA 27,25,10,10,8
We only use the CIRCLE statement to rotate this figure. In this program
the variable F sets the aspect ratio and the height for the centre point
of each circle. At first you will see the queen from the side. As you
rotate the figure to a top (or bottom) view, the circles will get rounder
and the centre points closer together.
PAGE 22
----------------------------------------------------------------------------
1.3.1.2 THE ASPECT RATIO IN CIRCLE FORMULAS.
The defualt aspect ratio is 0.44 at a screen resolution of 640*200.
Depending on the adjustment of your monitor, the value will draw circles
or ellipses. The best way to use the CIRCLE statement is with a variable
for the aspect ratio that you set at the start of your program. You only
have to chnage the variable once to change the program for different
monitors.
You can use any value between 0 and 200 for the aspect ratio. Using zero
will result in a horizontal line and using 200 will cause a similar action
only vertically.
When you set the aspect ratio smaller than one, the hoizontal distance from
the corner to the side will be equal to the radius. A value greater than one
makes the horizontal distance smaller than the radius and the vertical
distance equal to the radius. An aspect ratio of 1 will make the height and
width distances equal to the radius. You can calculate what the distance of
height and width will be for other aspect ratio values. To do this we must
understand how the CIRCLE statement computes it's path. The following program
uses everything we have learned so far about CIRCLE. Although a bit slow in
BASIC this program will help you understand the aspect ratio:
REM 1.3.1.2A Simulation of the CIRCLE statement.
CIRCLE (130,100),200,2,,,.2
CALL circlefunc (130!,100!,100!,1!,.2)
END
SUB circelfunc( mx,my,radius,colr,f) STATIC
FOR w = 0 TO 2*3.1415296# STEP .01
IF f<1 then
x = COS(w)*radius
Y = f * SIN(w) * radius
ELSE
x = COS(w)* radius/f
Y = SIN(w)* radius
END IF
PSET (mx+x,my+y),colr
NEXT w
END SUB
The above program shows you where to use the aspect ratio in a formula. It
is the factor that you multiply with X (for f smaller than one) and divide
with Y (for f greater than one). Knowing this we can calculate exactly what
distance a specific pixel will be from the centre. The following program
does this job for us by drawing radiuses.
PAGE 23
----------------------------------------------------------------------------
REM 1.3.1.2B Draw Radiuses.
CIRCLE (200,100),100,2,,,.2
x1 = 200
y1 = 100
FOR angle = 0 TO 6 STEP .5
x=x1
y=y1
CALL coordinates (x,y,100!,angle,.2)
LINE (x1,y1) - (x,y)
NEXT angle
END
SUB coordinates(mx,my,radius,w,f) STATIC
IF f<1 THEN
mx=mx+COS(w)*radius
my=my-f*SIN(w)*radius
ELSE
mx=mx+COS(w)*radius/f
my=my-SIN(w)*radius
END IF
END SUB
The subroutine calculates intersections and returns the results to the main
program. You can use the same sub-routine for all of the circles because
we pass all required parameters to it. The parameter that determines what
point you reach is the angle.In the above program we calculate 12 angles
between zero and six that set the circumferences for the circles. The sub
program then calculates the new values for the variables based on the
circle's centre point.
------------------------------------------
1.3.2 ANGLE PARAMETERS WITH CIRCLE.
The angle parameters are the last two parameters for the CIRCLE statement.
These parameters allow you to draw only a piece of a circle. The first angle
parameter sets the starting point of an arc and the secnd angle sets the end
point. Arcs are plotted counter clockwise. The CIRCLE statement looks like
this with all of the parameters:
CIRCLE(mx,my),radius,colour,start,end,aspect
If you used two CIRCLE statements with the same start and ends but swapped
you would draw a complete circle.
You can specify any start and end angles between -2*PI and 2*PI. You may
also know from your maths class that in curves 2*PI equals a full circle.
Here you might get the idea that using both maximum parameters (-2*PI and
2*PI) would draw two full circles. That is amthematically logical but false
in this case. The negative sign in this instance has no mathematical meaning
but rather a technical one.
PAGE 24
-----------------------------------------------------------------------------
If a start angle has a minus sign in front, a line is drawn connecting the
circle's centre to the curves starting point. This also applies to the
end angle value. The negative sign means smaller than zero. Even if you use
a minus sign in front of a zero, it is not negative. To start a curve with
an angle of zero and draw a line, you must use a value of -0.0001. This
value does not have much effect on the angle, but does tell the computer what
you want to do.
------------------------------------------------
1.3.3 RELATIVE ADDRESSING WITH CIRCLE.
We can also use relative addressing with the CIRCLE statement. When you draw
circles using relative addressing, the graphic cursor represents the centre
point. Unlike PSET and LINE, the graphic cursor does not move to the last
pixel drawn, but remains at the centre of the circle.
---------------------------------------------------
1.3.4 PIE CHARTS.
You have probably seen pie charts. For example, we could represent election
results using a pie chart to show who won how many seats. The pie sections
symbolize the total possible seats. The seats of one party are represented
by pieces of the pie in the party's colour. An election is only one of many
uses of the pie chart.
The Amiga can also display pie charts. Our program displays them almost the
same as those you have seen on television, in colour and three dimensional.
REM 1.3.4 Pie Charts
SCREEN 1,320,200,5,1
WINDOW 2,"Pie Charts",,,1
f= .3
pi=3.141529
start:
CLS
sum=0
INPUT "How many values";n
IF n<2 THEN
CLS
PRINT "Demo Program"
n = INT(RND(1)*10)+3
DIM value(n), colr(N)
PAGE 25
----------------------------------------------------------------------------
FOR i = 1 TO 10
value(i)=RND(l)*20+1
colr(i)=INT(RND(1)*31)
sum=sum+value(i)
NEXT i
ELSE
DIM value(n),colr(n)
FOR i = 1 TO n
value(i) = 1
PRINT i". Value";
INPUT value(i)
INPUT "Color";colr(i)
colr(i)=colr(i) MOD 32
sum = sum + value(i)
NEXT i
CLS
END IF
REM draw pie chart.
mx=WINDOW(2)/2
my=WINDOW(3)/2
w1=0
radius = mx-10
CIRCLE(mx,my+20),radius,1,pi,2*pi,f
LINE(mx-radius,my)-(mx-radius,my+20)
LINE(mx+radius,my)-(mx+radius,my+20)
LINE(mx,my)-(mx+radius,my)
FOR i = 1 TO n
w2=w1+2*pi*value(i)/sum
CIRCLE(mx,my),radius,1,-w1,-w2,f
REM Color statement.
x=COS(w1+(w2-w1)/2)*radius/2
y=-f*SIN(w1+(w2-w1)/2)*radius/2
PAINT STEP(x,y),colr(i),1
IF w2>pi THEN
REM Draw Side Line.
x=COS(w2)*radius
y=-f*SIN(w2)*radius
LINE (mx+x,my+y)-(mx+x,my+y+20)
REM Colour Side.
IF w2-.1>PI THEN
x=COS(w2-.1)*radius
y=f*SIN(w2-.1)*radius
PAINT (mx+x,my+y+18),colr(i),1
END IF
END IF
w1=w2
NEXT i
INPUT "New Graphic";a$
ERASE value,colr
IF a$<>"n" THEN start
WINDOW CLOSE 2
SCREEN CLOSE 1
PAGE 26
----------------------------------------------------------------------------
This program gives you the option of selecting your own values or using
randomly generated values. The demo program will start if you enter a zero
after the value query. If you enter your own values you can select any of
32 colours for eah value.
Each segment of the pie is drawn separately. Earlier we discussed how you
can draw a segment. All you need is a starting and ending angle. You place
a minus sign in front of each angle to draw the connecting lines from the
centre to the ends of the arc. To bring the colour into each segment we need
another statement. All you need is a framed surface and the coordinates of
a pixel within this frame to use the PAINT statement. The first requirement
was fulfilled when we drew the circle segment. To complete the second
requirement we have to use the circle formula that we used to demonstrate
the aspect ratio. You calculate the centre point of a segment with the
following:
x=COS(w1+(W2-W1)/2)*RADIUS/2
Y=-F*SIN(W1+(W2-W1)/2)*RADIUS/2
In this formula W1 is the start angle, W2 the end angle and F is the aspect
ratio (here it is always smaller than one). The X and Y variables are not
absolute window coordinates, but relative to the circle centre point.
This allows us to fill the segment with the following statement:
PAINT STEP (X,Y),colr(i),1
The variable colr(i) contains the colour with which we want to fill the
segment. The trailing one means we want the segment outlined in white.
We use a modified version of the formula that calculates centre points to
separate and colour the borders of the pie.
----------------------------------------------
1.3.5 PIXELS AND LINES WITH CIRCLE.
As silly as it may seem you can also plot pixels, not just ellipses and
circles, using the CIRCLE statement. We are not refering to the lines created
by setting the aspect ratio to zero as you saw above. Nor do we mean the
pixel set by using a radius of zero, neither of these actions have a
practical use. To draw useful lines and pixels we have to manipulate the
angle parameters.
We set pixels by using the start and end angle values that are equal. You
draw a line by making one of the equal signs negative. The distance of a
pixel or length of the line are set by the radius and the aspect ratio.
PAGE 27
----------------------------------------------------------------------------
In certain instances, drawing lines with this method is very useful. You
can draw a line for a specific length and angle from one point. To do this
with a LINE statement, you would need to know points and would have to
calculate the angle.
We can demonstrate the advantages of this unusual use of circle with the
following program. This is an analog clock that we can draw using only
the CIRCLE statement and no other graphic statements. You save a lot of time
and calculation effort because the program does not have to compute the
coordinates of the hands and minute divisions.
REM 1.3.5 Analog Clock.
pi=3.1415926#
f=.5 'aspect ratio'
REM Draw circle.
FOR i = .0001 TO 2*pi STEP pi/30
CIRCLE (100,100),97,1,i,i,f
NEXT i
REM Hours marks
FOR i = .0001 TO 2*pi STEP pi/6
CIRCLE (100,100),93,1,i,i,f
CIRCLE (100,100),90,1,i,i,f
NEXT i
st: INPUT "Hour ";hour
IF hour > 12 GOTO st
INPUT " Minutes ";minutes
hangle = -((12-hour)*60-minutes)*pi/360-pi/2.0001
mangle = -(60-minutes)pi/30-pi/2.0001
IF hangle <-2*pi THEN hangle = hangle + 2*pi
IF mangle <-2*pi THEN mangle = mangle + 2*pi
REM Hands
CIRCLE (100,100),85,2,mangle,-mangle,f
CIRCLE (100,100),70,3,hangle,-hangle,f
ON TIMER(60) GOSUB Timeout
TIMER ON
WHILE 1:WEND
Timeout:
REM Delete old hands.
CIRCLE (100,100),70,0,hangle,-hangle,f
CIRCLE (100,100),85,0,mangle,-mangle,f
hangle = hangle + pi / 360
mangle = mangle + pi / 30
IF hangle > 0 THEN hangle = hangle -2*pi
IF mangle > 0 THEN mangle = mangle - 2*pi
REM New Hands.
CIRCLE (100,100),85,2,mangle,-mangle,f
CIRCLE (100,100),70,3,hangle,-hangle,f
RETURN
The TIMER statement makes sure that we call the subroutine every minute
that updates the clock. This statement lets you bypass interrupt programming
which is something that you may not be familiar with. This method is much
more comfortable to use than the usual way of interrupt programming in
AmigaBASIC.
PAGE 28
----------------------------------------------------------------------------
Instead of the endless loop, WHILE 1: WEND, you could substitute your main
program. In this case it would be useful to place the clock within its
own window.
PAGE 29
----------------------------------------------------------------------------
1.4 AREA FILL.
So far you have learned several ways to draw different shapes. You used the
LINE statement to quickly draw colored rectangles on the screen.
The CIRCLE statement does not have a built in fill function so we stepped
ahead a bit and used the PAINT statement. This is the statement we are now
going to look at in detail.
---------------------------------------------
1.4.1 THE PAINT STATEMENT.
To paint simply means to fill an area with colour. The PAINT statement does
this with amazing speed. To do this, first specify the location of a pixel
inside the shape you want to paint. If the shape and fill colours are not the
same, add the shape colour at the end of the statement. The shape colour
tells the computer where to stop painting. You can specify the location using
either relative or absolute coordinates. Using a relative address after the
CIRCLE statement is easy because the graphic cursor is still located in the
center of the circle. You can see how easily we fill circles in the next
program.
REM 1.4.1 Fill Demo.
SCREEN 1,320,200,5,1
WINDOW 2,,(0,0)-(311,185),16,1
RANDOMIZE TIMER
WHILE INKEY$ = ""
f = INT(RND*32)
CIRCLE (RND*311,RND*185),RND*100,f
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
Compared to the rectangle program using LINE, this program fills in the
colour a little slower. The CIRCLE statement is one reason why this happens.
However, the PAINT statement fills in colour slower than the LINE statement
with a box fill function. This is because the PAINT statement has to check
every pixel for the shape border before painting.
You should be very careful when using PAINT. If the border of the area you
want filled has even one hole in it, the entire screen can be painted. The
same thing will happen if you specify a window type smaller than 16 (see
PAINT in the BASIC handbook). In this case, if the shape passes outside the
right window border, the entire window is filled. To test this, change the
16 in the last program to a zero.
PAGE 30
--------------------------------------------------------------------------
1.4.2 ANOTHER SOLUTION. AREA AND AREAFILL.
There is another way to fill an area besides using LINE and PAINT. Unlike
with PAINT, we do not need a border shape, instead we need single pixels as
corner points.
There are two statements used in this method. The first statement AREA, sets
all the corners. This statement is easier to use than PSET because no
colours are needed.
AREA (10,30)
AREA (199,140)
AREA STEP (200,-30)
As you can see, the AREA statement is used relatively.
The second statement, AREAFILL, tells the computer to paint the defined area.
AREAFILL
After entering the four statements you should see a white triangle on your
screen (WHAT FUCKIN FOUR STATEMENTS?!?!?!).
Because the power of these statements is their ability to create figures
with many corners, the triangle does not completely demonstrate this power.
The sequence of the corners you specify will determine what your figures will
look like. Although the order of three points does not make much difference,
with 4 points it is possible to have three different figures using the same
coordinates.
REM 1.4.2A Three Possible
AREA (10,10)
AREA (30,140)
AREA (60,100)
AREA (50,20)
AREAFILL
WHILE INKEY$="": WEND
CLS
AREA (10,10)
AREA (60,100)
AREA (50,20)
AREA (30,140)
PAGE 31
----------------------------------------------------------------------------
AREAFILL
WHILE INKEY$="": WEND
CLS
AREA (10,10)
AREA (60,100)
AREA (30,140)
AREA (50,20)
AREAFILL
The larger the number of corners, the greater the number of possible
connecting lines. A pentagram, which has 5 points and can be drawn by hand in
one motion, is a good example of this:
REM 1.4.2B PENTAGRAM
AREA (100,20)
AREA (140,100)
AREA (20,45)
AREA (180,40)
AREA (40,110)
AREAFILL
You will notice that in the completed star only the points are white but the
centre is still blue. To explain this we will use the same program again only
slightly changed:
REM 1.4.2C FRAMING BY DRAWING TWICE
FOR i = 0 TO 3
AREA (10,30)
AREA (199,140)
AREA STEP (200,-30)
NEXT
AREAFILL
By changing the program we have set each corner twice and filled each area
twice with AREAFILL. You might think that drawing twice works better, but
this is not true. Instead of a filled area we only see the border.
The pentagram is much the same. Like the triangle above, the pentagram's
centre is outlined twice and filled twice. Painting the same area a second
time has the same result as erasing it.
A figure with only 5 corners isn't very complicated. But if we create a
figure using 19 corners, it is difficult to detect all the corner points.
By using random values, you can create figures that resemble modern art.
PAGE 32
----------------------------------------------------------------------------
REM 1.4.2D 19 CORNERS.
WINDOW 1, "Modern Art",(0,0)-(615,185),15
Start:
CLS
RANDOMIZE TIMER
FOR i = 0 TO 18
AREA (RND+61,RND*185)
NEXT i
AREAFILL
WHILE INKEY$="": WEND
GOTO Start:
Since AREAFILL can only work on a maximum of 19 corners, if you try to set
more than this, nothing will be displayed on the screen. After and AREAFILL
statement, all the corner points are removed from memory and you can specify
new ones.
1.4.2.1 DIFFERENT MODES OF AREAFILL.
AREAFILL has two different modes. This first mode, which you already know
because we have been using it, always fills an area with the default
foreground colour. In our example we used white but you can change this by
using the COLOR statement.
COLOR 2
Once this statement is executed, the next area is filled with black. This is
the only way you can have a direct effect on the colour of an area. Since it
is the default mode, this mode does not require a lot of exlpanation. You
can specify this mode with a trailing zero:
AREAFILL 0
The second mode of AREAFILL inverts the area instead of filling the area.
REM 1.4.2.1A Invert Demo.
WINDOW 1,"INVERT DEMO",(0,0)-(615,185),15
PRINT "This is a Test!"
PRINT "All points inside"
PRINT "the triangle will be"
PRINT "Inverted!!"
CIRCLE (100,100),90,2
PAINT STEP (0,0),3,2
AREA (20,0)
AREA (180,45)
AREA (40,100)
AREAFILL 1
To indicate this mode enter a one after the AREAFILL statement. For each
pixel on the screen there is a series of bits in memory that specify it's
colour register. When we invert a pixel, each bit value changes to it's
opposite value. If a bit was equal to one it changes to zero and if it was
zero it changes to one. You can calculate the colour register change to a
pixel like this:
newcolor = (2^depth-1)=oldcolour
PAGE 33
-------------------------------------------------------------------------
The following program demonstrates how fast these program changes can
take place:
REM 1.4.2.1B SPEED
WINDOW 1,"SPEED TEST",(0,0)-(611,185),15
LOCATE 10,4
PRINT "SPEED IS NOT A MAGIC TRICK!"
WHILE INKEY$=""
FOR i = 0 TO 2
AREA (RND*611,RND*185)
NEXT i
AREAFILL 1
WEND
This program uses random corner points for a triangle and inverts everything
inside it. The loop repeats and creates many triangles on top each other in
blue and orange. The result is a screen full of blue and orange checks. The
longer the program runs, the more difficult it is to identify the individual
shapes.
---------------------------------------------
1.4.3 PATTERNS.
When a computer fills an area, it sets one pixel after another until the area
is filled with the selected colour. Besides performing this type of area fill
the Amiga can also fill an area with a pattern designed by you.
Patterns can improve a graphic image or make part of the picture stand out.
You can also create shadows and build textured walls easily with patterns.
Besides patterned areas, you can also draw patterned lines.
Both patterns and patterned line require the same statement. Since the
format is much the same for both, we will discuss patterned line first.
--------------------------------------------
1.4.3.1 PATTERN CREATION.
To create a pattern for a line, we use a 16 bit mask composed of 16 binary
numbers (ones and zeros). Each value of one in the mask equals a set pixel
in the pattern and each zero equals and empty position.
PAGE 34
----------------------------------------------------------------------------
After 16 pixels, the mask pattern repeats. Therefore you can only draw where
a mask bit is equal to one. This is similar to using a drawing template
because you can only draw where there is a hole.
Since AmigaBASIC cannot manipulate binary numbers, we have to convert the
binary mask value to hexadecimal. You could also convert the mask to decimal
but this is more complicated. To convert to hexadecimal we have to work with
four bits at a time. Our mask could look like this:
1011 0010 0000 1111
We convert each four bit block separately. To do this, we take the first bit
and multiply it by 8, the second bit and multiply it by 4 and it add to the
first. We then multiply the third bit by two and add, and then the last bit.
The result of this operation is a number between 0 and 15. In hexadecimal,
the numbers 10 thru 15 are converted to the letters A thru F. With our sample
mask the conversion looks like this :
1*8 + 0*4 + 1*2 + 1 = B (11)
0*8 + 0*4 + 1*2 + 0 = 2
0*8 + 0*4 + 0*2 + 0 = 0
1*8 + 1*4 + 1*2 + 1 = F (15)
By vertically reading the end of the lines above we have B20F. We can try
this out in our next program:
REM 1.4.3.1 PAtterned lines
PATTERN &HB20F
LINE (0,0)-(614,185)
LINE (20,30)-(104,105),2,B
As demonstrated, our pattern works not only on lines, but also on rectangles.
The label "&h" in front of the mask identifies the number as a hexadecimal
value.
------------------------------------------------
1.4.3.2 PATTERNED AREAS.
The pattern format for areas is similar to the format for line patterns. The
main difference is that areas are two dimensional. Because of this, you have
to stack many 16 bit masks, one on top of the other, to build an area pattern.
These masks are assigned using an array variable with the PATTERN variable.
PAGE 35
------------------------------------------------------------------------------
The pattern for lines is the first parameter. The pattern for the areas is
the second parameter and defined in an integer array variable.
REM 1.4.3.2 Pattern Maker.
DEFINT a
OPTION BASE 1
DIM a(8)
FOR i = 1 TO 8
READ a(i)
NEXT i
PATTERN ,a
COLOR 3,1
LINE (0,0)-(614,185),,bf
WHILE INKEY$="": WEND
COLOUR 1,0
CLS
DATA &H0,&H7FFF,&H7FFF,&H7FFF
DATA &H0,&HFF7F,&HFF7F,&HFF7F
The first thing you should do is make your array values all short integers.
This means only numbers between -32768 and 32767 or in hexadecimal 0 to FFFF.
If the variable type is wrong, you can create an error condition. To prevent
this, we declare the array as short integer using DEFINT at the beginning of
the program.
The DIM instruction tells PATTERN how many rows are in the pattern. You must
dimension the array even if there are less than 10 elements. The number of
array elements has to be equal to a power of two (1,2,4,8...). Should there
be one or more less, you will get an "illegal function call" error. With
normal arrays, you have to use the default array starting value of zero,
such as 0-3,0-7 etc. The ending index value is always smaller than the power
of two. Or you can use:
OPTION BASE 1
to set the default starting value of all arrays to one.
-------------------------------------------------
1.4.3.3 PATTERN DESIGN IN A PROGRAM.
As you saw above, calculating the pattern values yourself is a lot of work.
But when you have a computer that can do the work for you, why should you
do it?
All you need is a small program that understands the binary pattern mask and
converts it into hexadecimal or decimal. Since AmigaBASIC does not recognise
binary, we have written a small subroutine. This subroutine converts
character strings into short integers (numbers that memory sees as two bytes).
In the character string, you represent each zero with a space and any other
character equals a one. We selected the left Amiga button as the shape for
our pattern:
PAGE 36
----------------------------------------------------------------------------
REM 1.4.3.3 DESIGN IN LISTING.
WINDOW,1,"DESIGN PATTERNS",(0,0)-(617,185),15
OPTION BASE 1
a=8
DIM f$(a)
REM 0123456789ABCDEF
f$(1)=" *** "
f$(2)=" **** "
f$(3)=" * *** "
f$(4)=" * *** "
f$(5)=" ********* "
f$(6)=" ** *** "
f$(7)=" ***** *****"
f$(8)=""
REM 0123456789ABCDEF
CALL changeformat(f$(),a)
CIRCLE(400,140),100
PAINT STEP (0,0),2,1
AREA (150,160)
AREA (500,100)
AREA (570,170)
AREA FILL 1
MOUSE ON
WHILE INKEY$=""
IF MOUSE(0) <>0 THEN
b=MOUSE(1)
c=MOUSE(2)
IF b>0 AND b<600 AND c>0 AND c<172 THEN
LINE (b,c)-(b+4,c+4),1,bf
END IF
END IF
WEND
SUB changeformat (fd$(1),g) STATIC
DIM fd%(g)
FOR i = 1 TO g
fd$(i)=fd$(i)+SPACE$(16)
FOR j = 1 TO 3
h=0
FOR k = 1 TO 3
IF MID$(fd$(i),j*4+k+1,1)<>" " THEN h=h+2^(3-k)
NEXT k
fd%(i)=fd%(i)+VAL("&h"+HEX$(h*2^(4*(3-j))))
NEXT j
PRINT i, HEX$(fd%(i)),fd%(i)
NEXT i
PATTERN ,fd%
END SUB
First we convert the character strings from spaces and asterisks into a
pattern. Then we use this pattern to fill a circle and a triangle. The
program also allows you to draw with the mouse, using the defined pattern.
When you press the mouse button you can draw a 4*4 pixel sized rectangle
filled with the pattern.
PAGE 37
----------------------------------------------------------------------------
Two parameters are passed into the subroutine that converts the character
strings into hexadecimal values. The first parameter is the array where the
mask will be stored and the second parameter is the number of elements in the
array. We perform the conversion using the principles we explained earlier.
The subroutine then passed the pattern to the PATTERN statement.
Since calculating a pattern mask every time you run a program can be
troublesome, the above program is very useful as a pattern editor. For
example, change the Amiga-A pattern to any pattern you want to use. If you
want a different pattern , change the strings again. The calculated pattern
values are printed on the screen in decimal and hexadecimal. When the pattern
generated is the one you want, write down the values and insert them in your
own program.
-------------------------------------------------
1.4.3.4 PATTERNS AND THE CURSOR.
Patterns are supposed to be used with fill functions and should only affect
fill functions. However, a side effect occurs when defining a pattern. The
cursor is also changed. For example, in the previous program, the cursor
appeated after the program printed the pattern values in the output window,
but only as a small point. If you press the space bar you would see a dotted
line instead of the normal pattern. These dots come from the Amiga-A pattern.
If this changed cursor is disturbing, you can recover the normal cursor by
adding the following lines to the program.
REM Cursor REset
DIM norm%(2)
norm%(1) = &HFFFF
norm%(2) = &HFFFF
PATTERN ,norm%
It is very important that you use the statement "OPTION BASE 1" before
running these program lines. If you do not use OPTION BASE, you must decrement
all array values by one.
Of course, you could do the opposite and change the cursor on purpose. You
can make the cursor disappear when using INPUT or change it to a dashed line.
To create a dashed line make the value or norm%(2) in the last program equal
to zero. A half block cursor requires an array with eight elements. You
set the first four values to zero and the last four to &HFFFF for a bottom
half block cursor. To make a top block cursor just switch the four first and
last values.
PAGE 38
----------------------------------------------------------------------------
For a bottom half block cursor. To make a top block cursor, just switch
the four first and last values.
----------------------------------------
1.4.3.5 BRINGING IT TOGETHER
you can write some fantastic programs using pattern filled areas. The
program below is a good example of this.
REM 1.4.3.5A Stars and Stripes
DEFINT a-z
OPTION BASE 1
DIM a(a6)
SCREEN 1,320,200,5,1
WINDOW 2,,(0,0)-(311,185),16,1
FOR i= 1 TO 16
READ a(1)
NEXT i
PAINT (0,0),2
LINE (16,16)-(260,146),9,bf
FOR i= 0 TO 5
LINE(16,26+i*20)-(260,36+i*20),1,bf
NEXT i
PATTERN ,a
LINE (16,16)-(111,80),1,bf
DATA 0,1536,3840,-16,16320,8064
DATA 6528,0,0,96,240,4095,1020
DATA 504,408,0
WHILE INKEY$="": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
An American flag appears shortly after starting this program. We defined
the stars in a pattern containing two stars, one above the other. The top
star is centered and the other is slightly offset so the rows are not
vertically aligned.
As we hinted above, another possible use for patterns is to create 3-D
effects. We have a small demonstration program to illustrate this:
REM 1.4.3.5B 3-D
DEFINT a-z
REM 3-D Cubes
OPTION BASE 1
DIM c(4)
SCREEN 1,320,200,3,1
WINDOW 2,,(0,0)-(311,185),16,1
COLOR 0,1
CLS
REM Pattern
c(1)=&H1010
PAGE 39
---------------------------------------------------------------------------
c(2)=&H4040
c(3)=&H101
c(4)=&H404
PATTERN ,c
h=94
x=68
y=x/2
REM Large Cube
AREA (60,44)
AREA STEP (x,-y)
AREA STEP (x,y)
AREA STEP (0,h)
AREA STEP (-x,y)
AREA STEP (0,-h)
AREAFILL
SWAP c(1),c(4)
SWAP c(2),c(3)
PATTERN ,c
AREA STEP (0,0)
AREA STEP (-x,-y)
AREA STEP (0,h)
AREA STEP (x,y)
AREAFILL
REM Small Cube
COLOR 4
AREA STEP (0,-h/2)
AREA STEP (x/2,-y/2)
AREA STEP (0,-h/2)
AREA STEP (-x/2,-y/2)
AREA STEP (-x/2,y/2)
AREA STEP (0,h/2)
AREAFILL
SWAP c(1),c(4)
SWAP c(2),c(3)
PATTERN ,c
AREA STEP (0,0)
AREA STEP (x/2,-y/2)
AREA STEP (0,-h/2)
AREA STEP (-x/2,y/2)
AREAFILL
WHILE INKEY$="": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
You will see a 3-D cube standing on one of its corners. It appears that
either a small cube is missing or is stacked on top.
The patterns that we used to create the intersecting pieces are almost the
same. The only difference is the order we assign the values. To change from
one pattern to another, just reverse the order of the variables. In this
program we used to SWAP-assignments to take care of this.
PAGE 40
---------------------------------------------------------------------------
1.5 MEDLEY OF COLORS
The Amiga provides a palette of 4096 colors. If you use pure BASIC you can
only use 32 colors at a time (we'll show you how to use more later). The
specific colors are stored in the color registers. When you use a
statement, you are not selecting which color to use but which color
register to get the color from.
You cannot use all 32 colors in any type of screen. The number of possible
colors depends on the depth of your screen. A normal Workbench screen has a
depth of two, which allows you four colors. For every pixel there are two
bits in memory which determine those four colors.
00 Color register 0
01 Color register 1
10 Color register 2
11 Color register 3
To display 32 colors you need five bits per pixel, but first you have to
open a new screen with a depth of five:
SCREEN 1,320,200,5,1
WINDOW 2,"TITLE",(0,0)-(311,185),16,1
Now you could use all the statements you have learned so far with 32
colors.
Of the 32 colors available, you can select one for the foreground and one
for the background.
COLOR 1,0
These are the two default values. The first sets the foreground color and
the second sets the background color. All the graphic statements will use
these two colors. As longs as you leave the color parameter off, even PSET
will use the default foreground color, and PRESET will use the default
background color.
Changing the foreground and/or background, color does not instantly change
the screen colors. Using the CLS statement makes the new colors take
effect.
PAGE 41
---------------------------------------------------------------------------
COLOR 2,3
CLS
The above statement gives you an orange screen with a black foreground
color.
----------------------------------------
1.5.1 THE COMPLETE PALETTE
Most of the time you will probably want a completely different set of
colors in you program instead of the 32 default colors. To do this, you
have to change the colors in the color registers.
Every color is composed of three values which set the read, green and blue
of the color(RGB). Each of these values has a range from one to 4096.
The BASIC statement use to change the colors is PALETTE. You must specify
the RGB(red, green and blue) values and which color register to change. The
RGB color division must be a number between zero and one.
PALETTE 0,.75,1,0
This line sets a neon yellow background. This color is a mix of red and
yellow, blue is not used. To set the normal blue background:
PALETTE 0,0,.3,.6
Setting the red to one(1) and the other ranges to zero gives you red. This
procedure works the same for the other two ranges.
----------------------------------------
1.5.2 CHANGING RGB COLORS
You can find any color you want by experimenting with the three color
ranges. However, finding a specific color with this method could be tiring.
The following program allows you to search for and find your target color.
You can change all three ranges while the program is running and quickly
PAGE 42
----------------------------------------------------------------------------
find your desired combination. The results are visible on the screen at the
same time.
REM 1.5.2 ColorConstructor
SCREEN 1,320,200,2,1
WINDOW 2,"ColorConstructor",(0,0)-(297,185),31,1
LINE (200,20)-(300,150),3,bf
LOCATE 5
PRINT "> '4' '5' '6'"
LOCATE 16
PRINT "< '1' '2' '3'"
LOCATE 10
PRINT " R G B"
r=1:g=.5:b=0 ' orange
WHILE 1
LOCATE 11
PRINT USING " #.##";r;g;b
PALETTE 3,r,g,b
WHILE A$=""
A$=INKEY$
WEND
IF A$<>"" THEN
IF A$="1" and r>=.0666 THEN r=r-.06666
IF A$="4" and r>=.9333 THEN r=r+.06666
IF A$="2" and g>=.0666 THEN g=g-.06666
IF A$="5" and g>=.9333 THEN g=g+.06666
IF A$="3" and b>=.0666 THEN b=b-.06666
IF A$="6" and b>=.9333 THEN b=b+.06666
END IF
WEND
You can change the color ranges by using the 1-6 keys. The numeric keypad
is perfectly arranged for changing color ranges. The 4 key raises and the 1
key lowers it. The 5 and 2 keys raise and lower the green range, and the 6
and 3 keys raise and lower the blue range.
The color range will increase and decrease by a value of 0.0666 or 1/15.
This insures a color range with every keypress.
You can also change the mouse pointer colors with the PALETTE. The effected
registers are 17,18 and 19. Try it out.
----------------------------------------
1.5.3 THE OPPOSITE OF PALLETTE
In many programs it is very important to know what colors are in the
palette. However, there is no statement in BASIC that performs the opposite
of PALETTE. Again we will step ahead a little and get out our data directly
PAGE 43
----------------------------------------------------------------------------
from memory. We will explain later, when we leave pure BASIC, how to
detemine the address of the color table.
Since the functions assigned at the beginning of the program take care of
any addresses or PEEKs, you do not have to concern yourslef with these. You
just have to provide the color register number to the function. There are
three functions, one for each RGB color range.
REM 1.5.3 Palette-Opposite
SCREEN 1,320,200,5,1
WINDOW 2,,,16,1
DEF FNcolortab=PEEKL(PEEKL(PEEKL(WINDOW(7)+46)+48)+4)
DEF FNred(f)=(PEEKW(FNcolortab+2*f) AND 3840)/3840
DEF FNgreen(f)=(PEEKW(FNcolortab+2*f) AND 240)/240
DEF FNblue(f)=(PEEKW(FNcolortab+2*f) AND 15)/15
PRINT "RGB Color Values:"
FOR i = - TO 31
LOCATE 5+i MOD 16,1+INT(i/16)*20
COLOR i
PRINT USING "##";i,
COLOR 1
PRINT USING " #.##";FNred(i);FNgreen(i);FNblue(i)
NEXT i
WHILE INKEY$="":WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
This program prints out the color values for evry color. The color register
and color are listed in front of the three ranges.
----------------------------------------
1.5.4 ANIMATION USING COLOR
Now we'll show you away to make functions from the last program useful. You
can easily animate a picture by repeatedly swapping several colors. This
color cycling trick may be familier to you because paint programs, such as
GraphiCraft and Deluxe Paint, use it. You can magically display moving
rivers or similar actions with this method. With some porgramming, this
color swapping is possible in BASIC. However, you should keep the number of
colors being swapped as small as possible because of BASIC's slowness. If
you use too many colors, the cycling will be slower, causing a jerky and
ragged look.
REM 1.5.4 Palette-Opposite Expanded
SCREEN 1,320,200,5,1
WINDOW 2,,,16,1
PALETTE 0,0,.5,0
PALETTE 28,0,.35,.72
PAGE 44
----------------------------------------------------------------------------
PALETTE 29,0,.35,1
PALETTE 30,0,.5,1
PALETTE 31,0,.6,1
DEF FNcolortab(PEEKL(PEEKL(WINDOW(7)+46)+48+4)
DEF FNred(f)=(PEEKW(FNcolortab+2*f) AND 3840)/3840
DEF FNgreen(f)=(PEEKW(FNcolortab+2*f) AND 240)/240
DEF FNblue(f)=(PEEKW(FNcolortab+2*f) AND 15)/15
f1=28:f2=31
FOR j=0 TO 311 STEP 4
FOR i=0 to 3 STEP .5
LINE (j+i,120+j/8)-(J+i-4,140+j/8),28+i
LINE (j+i+1,120+j/8)-(J+i-3,140+j/8),28+i
NEXT i
NEXT j
rotation:
r1=FNred(f2)-.03
g1=FNgreen(f2)-.03
b1=FNblue(f2)-.03
FOR i=f1 TO f2
r=FNred(i)-.03
g=FNgreen(i)-.03
b=FNblue(i)-.03
PALETTE i,r1,g1,b1
r1=r
g1=g
b1=b
NEXT i
GOTO rotation
This program draws an abstract river. We set the last eight color registers
to blue for the river.
In the program routine "rotation" we subtract .03 from the recieved color
range before using the value with PALETTE. This corrects a calculation
error for the floating point value, that is between 0 and 15, which we
received from memory.
PAGE 45
----------------------------------------------------------------------------
1.6 ALL ABOUT PUT AND GET
The PUT and GET statements have many uses, which include saving your
graphcis on disk and working with animation. However, all the PUT and GET
capabilities have one thing in common: the managment of screen information.
----------------------------------------
1.6.1 USING PUT AND GET
With GET you can read a graphic from a specific region and with PUT you can
draw it. We store the data in an array variable defined as integer. By
using values between -32768 and 32767, building the data array is easier.
1. Array position = width
2. Array position = height
3. Array position = depth
4. Array position = bit-planes
Starting with fourth array element are the bit-planes. The depth of a
graphic detemines how many bits are used for each pixel. The first
bit-plane contains all the first bits, the second all the second bits, etc.
This is also why the depth sets the number of bit-planes. The number of
elements in array will differ greatly depending on the graphics mode, width
values and height values.
To store data in integer form, we combine 16 bits of one bit-plane and one
screen line. Since we cannot store more than this in a short integer, we
have to devide the width by 16 when assigning array space. If there is a
remainder(the width did not devide evenly by 16), we have to round off. The
last pixel of a line is cut off if you do not round off. Now multiply this
value with the height and depth to get number array elements. You will
always have the three elements for width, height and depth. The following
formula will calculate the number of elements required:
Arrayspace=3+Height*Depth*INT((width+15)/16)
The first program in this section simply stores the screen contents with
GET, clears the screen and restores the old contents.
PAGE 46
----------------------------------------------------------------------------
REM 1.6.1 Demo for GET and PUT
OPTION BASE 1
DEFINT f
CIRCLE (170,60),110
PAINT STEP (0,0),2,1
COLOR 1,2
LOCATE 5,10
PRINT "This demo shows"
PRINT "How to store"
PRINT "graphics to memory"
PRINT "and also how to"
PRINT "display them again"
PRINT "on the screen!!!!"
AREA (140,20)
AREA (80,60)
AREA (300,80)
AREAFILL 1
COLOR 1,0
REM Save Graphic.
x1 = 40: y1 = 10
x2=300 : y2 = 120
DIM feld(3+2*(y2-y1+1)*INT((x2-x1+16)/16))
GET (x1,y1)-(x2,y2),feld
REM Redisplay Graphic
FOR i = 0 TO 140
CLS
PUT (i*3,i),feld
NEXT i
The first 20 lines of the above program draw the graphics. We used the top
left and lower right corners of this image to calculate how much array
space to dimension.
We can easily check whether or not our calculation assigned enough space.
Instead of adding the three required values in the formula, try adding only
two . As soon as the program starts,an "illegal function call" error will
appear on the screen. This error will always appear on the screen. This
error will always appear when you fail to reserve enough space for GET. As
long as you have plenty of memory, you can never assign too much space.
This demonstration shows you more than just how these statements work; you
can also see how fast the graphics move around the screen. The motion is so
smooth you can even read the moving text. As you have witnessed, moving
graphics and animation is easy when you use PUT and GET.
PAGE 47
----------------------------------------------------------------------------
1.6.2 SAVING TO DISK.
You have seen how to store screen information in memory using arrays. But
we cannot just leave the data in memory, because when you turn the computer
off the data will be lost. In order to permanently keep your graphic, you
must save it on disk. The following program contains subroutines for saving
and loading and can be used in other programs.
This program is also good for painting. When the program starts you have a
single pixel brush that has four colors. You can save your drawing to disk
and then load it again to use as a brush.
REM 1.6.2 Paint Program
OPTION BASE 1
DEFINT a-z
PRINT "Draw with the mouse"
PRINT "When you want to save part"
PRINT "Part of your graphic, press the "
PRINT "S key. To load a graphic press"
PRINT "the L key."
PRINT "Press the 'E' key to exit"
WHILE a$<>"e"
a$=INKEY$
WHILE a$=""
IF MOUSE(0)<>0 THEN
PSET(MOUSE(1),MOUSE(2))
END IF
a$=INKEY$
WEND
IF a$="l" THEN GOSUB picload
IF a$="s" THEN GOSUB picsave
IF a$>="0" AND a$<"4" THEN COLOR VAL(a$)
WEND
END
picload:
DIM fd(10000)
WINDOW 2,,(0,0)-(600,0).16
INPUT "Load file :";b$
IF b$<>"" THEN
CALL loader(b$,fd())
END IF
WINDOW CLOSE 2
WHILE INKEY$=""
IF MOUSE(0)<>0 THEN
PUT(MOUSE(1),MOUSE(2)),fd
END IF
WEND
ERASE fd
RETURN
PAGE 48
----------------------------------------------------------------------------
picsave:
WINDOW 2,,(0,0)-(600,0).16
INPUT "Save file : ";b$
IF b$<>"" THEN
PRINT "Position the corner points";
PRINT "with the mouse";
1 IF MOUSE(0)=0 THEN 1
ax=MOUSE(1):ay=MOUSE(2)
2 IF MOUSE(0)<> 0 THEN 2
3 IF MOUSE(0)=0 THEN 3
bx = MOUSE(1):by = MOUSE(2)
WINDOW CLOSE 2
CALL saver(b$,ax,ay,bx,by,2)
ELSE
WINDOW CLOSE 2
END IF
RETURN
' The following SUBroutines work without the main program
SUB saver (n$,x1,y1,x2,y2,dp) STATIC
e=3+(y2-y1+1)*dp*INT((x2-x1+16)/16)
DIM graphic%(e)
GET (x1,y1)-(x2,y2),graphic%
OPEN n$ FOR OUTPUT AS #1
FOR i = 1 TO e
WRITE #1,graphic%(i)
NEXT i
CLOSE #1
ERASE graphic%
END SUB
SUB loader (filename$,graphic%(1)) STATIC
OPEN filename$ FOR INPUT AS #1
INPUT #1,graphic%(1),graphic%(2),graphic%(3)
e=3+graphic%(3)*graphic%(2)*INT((graphic%(1)+15)/16)
FOR i = 4 TO e
INPUT #1,graphic%(i)
NEXT i
CLOSE 1
END SUB
If you want to save the entire screen, you wont have enough memory
assigned. To avoid this problem use the following statement once before
starting the program:
CLEAR ,40000
To be able to load a full screen again you also have to change a variable
dimension. At the program label PICLOAD raise the DIM statement for fd to
15000.
PAGE 49
----------------------------------------------------------------------------
There are also a few things you must do when you use the load and save
subroutines in your own programs.
For the save subroutine, you have to pass the following variables: data
name, upper left and lower right hand corner coordinates and the depth.
For the load subroutine you need the data name and an array that is large
enough to hold the data. To prevent errors, it is much safer to assign an
array larger than you need.
You can switch between, and use, load and save routines as often as you
like. The ERASE statement at the end of the save subroutine handles any
variable problems. Because variables retain their values between subroutine
calls, a "duplicate definition" error would appear if we had not used
ERASE.
We manage the loading and saving on disk with the standard data file
handling statements OPEN,INPUT,WRITE and CLOSE. You use OPEN and CLOSE to
open and close a disk data file. When you open a file you also indicate if
you are going to read or write data. To write data into a sequential file
use the WRITE statement. Each data value is sent to the the file one after
another, like entering characters on the keyboard.
When you are loading , load the width, height and depth before loading the
bit-planes. Then calculate the size of the array and determine how many
elements are loaded.
--------------------------------------------
1.6.3 ALTERNATIVE USES FOR PUT
In the last program you probably noticed an interesting side-effect caused
by the PUT statement. Passing over an existing image on the screen caused a
blending of the image. Maybe you also discovered that when you get the same
graphic twice in the same place, the graphic is erased.
---------------------------------------------
1.6.3.1 DEFAULT MODE OF PUT.
Both of these effects are side effects of the PUT statement. Instead of
painting over what is on the screen, PUT links the new pixel with the
existing one by using XOR. The logic table for XOR look like this:
PAGE 50
----------------------------------------------------------------------------
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
When two points line up exactly, the pixel is erased. A pixel is drawn only
when a set and unset pixel are on top of each other. Since this is not
always the best use of PUT, you can modify this effect. You can use
additional statements, called action-verbs after PUT for specific needs.
The default "action-verb" for PUT is XOR as we demonstrated in the last
program. Written out the statement would have the following syntax:
PUT (x,y),feld,XOR
You can easily move an objecy, without changing it, across a background and
create quality animation. The ball in the next program does this:
REM 1.6.3.1 Moving Pictures with PUT.
DEFINT g
COLOR 2,0
LOCATE 10,10
PRINT "This program moves a ball"
LOCATE 11,10
PRINT "Around the screen without"
LOCATE 12,10
PRINT "changing the text!!"
DIM g(250)
CIRCLE (20,20),20,1,,,.5
PAINT (20,20),3,1
GET (0,10)-(40,30),g
PUT (0,10),g,XOR
WHILE INKEY$= ""
FOR i = 0 TO 180
PUT(2*i,i),g,XOR
PUT(2*i,i),g,XOR
NEXT i
WEND
When you use the PUT statement twice in the same location you get your old
picture back.
This simple animation can be compared to the effects created by using
sprites on a Commodore 64 but these effects are more difficult to create.
You can achieve many other sprite type effects using different modes of the
PUT statement.
PAGE 51
----------------------------------------------------------------------------
The secret of the different modes and the speed of the PUT statement is a
graphic coprocessor called the Blitter. The blitter can move data around in
memory with incredible speed.
Not only does the blitter move data fast, it can also perform operations
like XOR at the same time.
------------------------------------------------
1.6.3.2 A DIRECT METHOD USING PSET.
The blitter can also skip any special operations and put the data directly
on the screen. To achieve this direct, but not necessarily faster method,
use the PSET mode.
Remove one of the PUT statements (PUT(2*i,i)g,XOR) in the last program.
Then replace the XOR in the next PUT line with PSET. Now you can see the
difference. The graphic, which is drawn over the whole screen, erases
nothing and draws over anything in its path. We not only have the ball, but
the entire rectangle that we saved with the GET statement. Even the white
locations change on the screen using PUT-PSET.
--------------------------------------------------
1.6.3.3 INVERTING GRAPHICS.
Similar to using PSET amd PRESET for setting pixels there is an opposite for
PUT-PSET called PRESET. By using the PRESET mode you can effortlessly
invert graphics. You only need two lines for this:
GET (X1,Y1)-(X2,Y2),g
PUT (X1,Y1),g,PRESET
The variable g is an integer that you must define before entering these
lines so that enough memory will be assigned.
Inverting a graphic means inverting each bit of the graphic. All ones
become zeros and all zeros become ones. This also causes the colours to
come from different colour registers. You can calculate the new colour
register like this:
New register = 2^ depth of graphic - old register.
How the colours change is demonstrated in this next small program.
PAGE 52
----------------------------------------------------------------------------
REM 1.6.3.3A Color change with PRESET.
DEFINT f
DIM f(400)
SCREEN 1,320,200,5,1
WINDOW 2,,(0,0)-(287,30),16,1
FOR i = 1 TO 31
LINE (i*9,0)-(i*9+8,40),i,bf
NEXT i
WHILE INKEY$=""
FOR i = 31 TO 0 STEP -1
GET (i*9,0)-(i*9+8,40),i,bf
PUT (i*9,0),f,PRESET
NEXT i
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
There are two different ways to restore a picture that you have inverted
using PUT-PRESET. The first is to invert the same area again.
We use the method in the following program. A rectangle will wander around
the screen. Every time it appears we invert the area it is in. Before the
rectangle moves again we invert the area a second time so that the old the
rectangle is visible again:
REM 1.6.3.3B Invert demo.
DEFINT f
DIM f(100)
CIRCLE (160,80),100,1
PAINT STEP (0,0),2,1
LINE (120,50)-(150,160),1,b
PAINT (121,51),3,1
PAINT (179,159),1,1
WHILE INKEY$=""
FOR i = 1 TO 160
GET (i,i)-(i+20,i+20),f
PUT (i,i),f,PRESET
FOR t = 0 TO 200:NEXT
GET (i,i)-(i+20,i+20),f
PUT (i,i),f,PRESET
NEXT i
WEND
The second method is much shorter and easier. After inverting, draw the
graphic in the same position again using PUT-PSET.
---------------------------------------------
1.6.3.4 AND or OR
The logic functions AND and OR are two additional modes for switching with
PUT. Like XOR, they operate on the individual bits of a pixel, which
determine its colour instead of the whole pixel.
PAGE 53
----------------------------------------------------------------------------
If both the screen pixels and the pixel stored with GET are equal to one
the AND will have a value of one. The following combinations are possible
with a depth of two and a maximum of four colours :
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
The following colours result:
If a pixel is blue (00), the second colour has no effect; it stays blue
(00). Orange (11) and another colour change the pixel to the other colour.
When both colours are the same there is no change. White (01) and black
(10) changes to blue (00).
The following is a short program that will demonstrate these combinations.
REM 1.6.3.4 AND switch.
DEFINT f
CIRCLE (160,80),100,1
PAINT STEP (0,0),2,1
LINE (120,50)-(180,160),1,b
PAINT (121,51),3,1
PAINT (179,159),1,1
PRINT "test"
GET (0,0)-(39,8),f
FOR i = 20 TO 160 STEP 8
PUT (i,i),f,AND
NEXT i
With GET, we store the word "test" as a graphic. Then we PUT this graphic
in various locations on a four coloured screen. As in the table above, our
white text is only visible with the orange and white backgrounds.
When we substitute OR for the AND we achieve an opposite effect. The text
is visible in the blue and black backgrounds and the blue background of the
text is not visible at all. The logic table for OR is:
0 OR 0 = 0
0 OR 1 = 1
1 OR 0 = 1
1 OR 1 = 1
PAGE 54
----------------------------------------------------------------------------
1.7 ANIMATION IN BASIC
As an owner of an Amiga, you should be very proud of it's highly praised
animation cability. You can easily run animations in BASIC by using many
built-in statements that start with OBJECT.
To create unusual effects you have to understand how these statements work
and how to use them. The BASIC handbook lists all of the statements but
does not show you everything you can do with them. For example, how to
create a bob is left to the included program and the other statement
explanations are too brief. Some very interesting things like the
COLLISION mask, are not even mentioned.
-------------------------------------------------
1.7.1 SPRITES AND BOBS.
The animation statements of BASIC are used for both sprites and bobs and are
limited to one or the other. Since sprites and bobs could be something new
to you here is a short definition.
Both sprites and bobs are moving graphics. Many of us have seen sprites on a
Commodore 64 and other home computers. On the Amiga, a sprite can be 16
pixels wide, as high as the screen and have up to three different colours.
Sprites can move very quickly and require little programming effort to
control.
Bobs are similar to sprites, but are designed for other uses. A bob can be
any size you want and is liited only by the amount of available memory.
Depending on the depth of the screen, a bob can have up to 32 colours. Bobs
move slower than sprites and are displayed on the screen using different
technology.
Another difference between bobs and sprites, which we'll discuss later, is a
set or unset bit in a register. Using more than 4 sprites can get compilcated
but the number of bobs you can use is limited only by the amount of memory.
PAGE 55
-----------------------------------------------------------------------------
1.7.2 THE OBJECT.SHAPE STATEMENT.
Unlike with the Commodore 64, you do not have to put the bob and sprite data
into memory. The OBJECT-SHAPE statement does this for you. After entering all
the required data using a character string, pass it to the OBJECT-SHAPE
statement. This is the only method that you can use in BASIC to define an
object.
Because a character string that contains the data for a sprite or bob has a
special format, the OBJECT-SHAPE statement will not understand just any
character string. The following detailed explanation shows you how to define
your own objects.
--------------------------------------------
1.7.3 DESIGNING AN OBJECT.
There are program included with BASIC, like the OBJEDIT program, that makes
object editing easy for you. Although OBJEDIT is adequate for most uses, it
cannot handle self-defined collision masks or shadow pictures (We will
explain later what these are and how to use them).
Why do you have all these fantastic possibilities but lack the software to
use them ??. Read on, we can solve this problem.
--------------------------------------------
1.7.4 THE COMPLETE OBJECT EDITOR : EDDI II
Eddi II, which has more options than OBJEDIT, is a program that lets you
design any type of object. With this program you can create objects with a
width of up to 309 pixels and a height of up to 183 pixels. You can also
change the screen depth, which affects different parameters of the object and
test your object while in the program. There are so many drawing statements
that you can use for painting. When you are satisfied with your design, you
can save it on disk as an object or as a graphic to be loaded with the PUT
statement.
The program itself is more convincing than anything we can say about it.
Because of the length of the program you need a minimum of 512K to use it.
PAGE 56
-----------------------------------------------------------------------------
REM ***************************************
REM 1.7.4 EDDI II
REM ***************************************
REM
REM
REM JENS TRAPP
REM
CLEAR ,42000 ' Increase work buffer.
OPTION BASE 1
DEFINT a-r,t-z
DEF FNe(b,h,t)=(3*t*h*INT((b+15)/16))
REM sprite colours.
DIM sr(3), sg(3), sb(3)
sr(1)=1 : sg(1)=1 : sb(1)=1 'white
sr(2)=0 : sg(2)=0 : sb(2)=0 'black
sr(3)=1 : sg(3)=.53 : sb(3)=0
REM Change Menus.
MENU 1,0,1,"Window"
MENU 1,1,1,"Load"
MENU 1,2,1,"Save"
MENU 1,3,1,"Size"
MENU 1,4,1,"Test"
MENU 1,5,1,"Delete"
MENU 1,6,1,"Quit"
MENU 2,0,1,"Tools"
MENU 2,1,2," Points 0"
MENU 2,2,1," Lines"
MENU 2,3,1," Frames"
MENU 2,4,1," Boxes"
MENU 2,5,1," Circles"
MENU 2,6,1," Fill"
MENU 3,0,1,"Depth"
MENU 3,1,1," 1 "
MENU 3,2,1," 2 "
MENU 3,3,1," 3 "
MENU 3,4,1," 4 "
MENU 3,5,2," 5 "
MENU 4,0,1,"Flags"
MENU 4,1,1," Sprite "
MENU 4,2,1," Collision"
MENU 4,3,1," Shadow "
MENU 4,4,2," Saveback "
MENU 4,5,2," Overlay "
MENU 4,6,1," SaveBob "
MENU 4,7,1,"PlanePick "
MENU 4,8,1,"PlaneOnOff "
MENU 4,9,0,"SpriteColor"
ON MENU GOSUB domenu 'Activate menus.
MENU ON
MOUSE ON
REM default values.
sdepth = 5 ' screen depth
gdep = sdepth ' Depth of graphic.
wd = 100 ' width
ht = 100 ' height
thick = 0 ' brush thickness
DIM fd(FNe(wd,ht,gdep))
PAGE 57
-----------------------------------------------------------------------------
pcolor = 1 ' Color = white.
fcolor = 1 ' Framecolour = white.
tool = 1 ' Default toll = "Point"
REM flags for standard objects.
planepick = 2^gdep-1
saveback = 1
overlay = 1
REM build screen
SCREEN 1,320,200,sdepth,1
WINDOW 2,,,16,1
GOSUB makescreen
Mainloop:
a$=INKEY$
WHILE a$=""
IF MOUSE(0)<>0 THEN GOSUB droutine
a$ = INKEY$
WEND
REM change format.
IF ASC(a$)=28 and ht>1 THEN
LINE (0,ht+1)-(wd+1,ht+1),8
ht = ht - 1
fd(2) = ht
LINE (0,0)-(wd+1,ht+1),fcolor,b
END IF
IF ASC(a$)=29 AND ht<184 THEN
LINE (1,ht+1)-(wd,ht+1),0
ht = ht + 1
LINE (0,0)-(wd+1,ht+1),fcolor,b
END IF
IF fvsprite = 0 THEN
IF ASC(a$)=31 AND wd>1 THEN
LINE (wd+1,0)-(wd+1,ht+1),8
wd=wd-1
fd(1)=wd
LINE (0,0)-(wd+1,ht+1),fcolor,b
END IF
IF ASC(a$)=30 AND wd<WINDOW(2) THEN
LINE (wd+1,1)-(wd+1,ht+1),0
wd = wd + 1
LINE (0,0)-(wd+1,ht+1),fcolor,b
END IF
IF ASC(a$) = 139 THEN
ERASE fd
DIM fd(FNe(wd,ht,sdepth))
GET (1,1)-(wd,ht),fd
LOCATE 24,1
PRINT "Set the size using the mouse";
WHILE MOUSE(0)=0: WEND
wd=MOUSE(1): IF wd>WINDOW(2) THEN wd=WINDOW(2)
ht=MOUSE(2): IF ht>184 THEN ht=184
GOSUB makescreen
END IF
END IF
IF ASC(a$)>47 AND ASC(a$)<58 THEN thick = ASC(a$)-48: MENU 2,1,1-(tool)=1," Points"+STR$(ASC(a$)-48)
IF a$<>"q" THEN MainLoop
PAGE 58
-----------------------------------------------------------------------------
endprog:
WINDOW CLOSE 2
SCREEN CLOSE 1
MENU RESET
END
makescreen:
COLOR 1,0: CLS
fd(3)=gdep
PUT (1,1),fd,PSET
sh2:
LINE (0,0)-(wd+1,ht+1),1,b 'Graphic frame.
LINE (wd+2,0)-(WINDOW(2),WINDOW(3)),8,bf
LINE (0,ht+2)-(wd+2,WINDOW(3)),8,bf
GOTO tf 'Color palette.
domenu:
title=MENU(0)
pnt = MENU(1)
ON title GOTO wndow,tools,gdepth,flags1
RETURN
gdepth:
MENU 3,gdep,1
planepick=pnt^2
IF pnt<gdep THEN
ERASE fd
DIM fd(FNe(wd,ht,sdepth))
GET (1,1)-(wd,ht),fd
gdep = pnt
GOTO makescreen
END IF
gdep = pnt
tf: MENU 3,gdep,2
LINE (0,186)-(WINDOW(2),WINDOW(3)),8,bf
FOR i = 0 TO 2^gdep-1
LINE (30+i*8,186)-(37+i*8,195),i,bf
NEXT i
IF pcolor>2^gdep-1 THEN pcolor = 1
IF fcolor>2^gdep-1 THEN fcolor = 1
GOTO colors2
wndow:
ON pnt GOTO loader,saver,size,test,del,endprog
RETURN
tools:
MENU 2,tool,1
tool = pnt
MENU 2,tool,2
IF tool=6 THEN
fcolor = pcolor
LINE (0,0)-(wd+1,ht+1),fcolor,b
GOTO colors2
END IF
RETURN
flags1:
ON pnt GOTO fvsprite1,coll1,shadmask1,saveback1,overlay1,savebob1,planepick1,planeoff1,sprcolor
RETURN
fvsprite1:
fvsprite = (fvsprite+1)MOD 2
PAGE 59
-----------------------------------------------------------------------------
fvsprite2:
IF fvsprite=1 THEN
MENU 4,1,2
MENU 4,9,1
FOR i = 1 TO 3
PALETTE i,sr(i),sg(i),sb(i)
NEXT i
FOR i = 2 TO 8
MENU 4,i,0
NEXT i
gdep = 2
IF wd<16 THEN
f=0
ELSE
f=8
END IF
LINE (18,0)-(wd+1,ht+1),f,bf
wd=16
LINE (0,0)-(wd+1,ht+1),fcolor,b
FOR i = 1 TO 5
MENU 3,1,0
NEXT i
MENU 3,2,2
collmask = 0
shadmask = 0
saveback = 0
overlay = 0
savebob = 0
planeonoff = 0
ELSE
MENU 4,9,0
MENU 4,1,1
PALETTE 1,1,1,1
PALETTE 2,0,0,0
PALETTE 3,1,.53,0
FOR i = 2 TO 8
MENU 4,i,1
NEXT i
gdep = 5
MENU 3,0,1
FOR i = 1 TO 4
MENU 3,i,1
NEXT i
MENU 3,5,2
END IF
planepick = 2^gdep-1
GOTO tf
coll1:
collmask = (collmask+1) MOD 2
coll2:
IF collmask = 1 THEN
b=0
CALL filename("Collisionmask",coll$,b)
IF coll$ = "" THEN collmask = 0
END IF
MENU 4,2,1+collmask
PAGE 60
-----------------------------------------------------------------------------
RETURN
shadmask1:
shadmask = (shadmask + 1) MOD 2
shad2:
IF shadmask = 1 THEN
b=0
CALL filename("ShadowMask",shad$,b)
IF shad$ = "" THEN shadmask = 0
END IF
MENU 4,3,1+shadmask
RETURN
saveback1:
saveback = (saveback+1) MOD 2
MENU 4,4,1+saveback
RETURN
overlay1:
overlay = (overlay+1) MOD 2
MENU 4,5,1+overlay
RETURN
savebob1:
savebob = (savebob+1) MOD 2
MENU 4,6,1+savebob
RETURN
planepick1:
CALL planes("PlanePick",planepick)
RETURN
planeonoff1:
CALL planes("Planeonoff",planeonoff)
RETURN
sprcolor:
WINDOW 3,"Sprite Color",(0,0)-(200,40),16,1
INPUT "Color 1,2 or 3";a
IF a>0 AND a<4 THEN
INPUT "Red range : ";sr(a)
INPUT "Green range:";sg(a)
INPUT "Blue range :";sb(A)
PALETTE a,sr(a),sg(a),sb(a)
END IF
WINDOW CLOSE 3
RETURN
droutine:
x = MOUSE(1)
y = MOUSE(2)
xalt = MOUSE(3)
yalt = MOUSE(4)
IF y>185 THEN colors
IF x>wd OR x<1 OR y>ht OR y<1 THEN RETURN
ON tool GOTO pnte,w,w,w,w,fillroutine
w:
IF MOUSE(0) <> 0 THEN
f1=POINT(xalt,yalt)
PSET(xalt,yalt),-(f1=0)
f2=POINT(x,y)
PSET(x,y),-(f2=0)
PSET(x,y),f2
PSET(xalt,yalt),f1
ELSE
PAGE 61
-----------------------------------------------------------------------------
ON tool GOTO droutine,linetool,frametool,boxtool,circletool
END IF
GOTO droutine
del:
LINE(1,1)-(wd,ht),0,bf
RETURN
pnte:
x1=x+thick: IF x1>wd THEN x1=wd
y1=y+thick: IF y1>ht THEN y1=ht
LINE (x,y)-(x1,y1),pcolor,bf
RETURN
linetool:
LINE(x,y)-(xalt,yalt),pcolor
RETURN
frametool:
LINE (x,y)-(xalt,yalt),pcolor,b
RETURN
boxtool:
LINE (x,y)-(xalt,yalt),pcolor,bf
RETURN
circletool:
IF y<>yalt AND x<>xalt THEN
r=ABS(x-xalt):v=ABS(y-yalt)
IF v<r THEN
CIRCLE(xalt,yalt),r,pcolor,,,v/r
ELSE
CIRCLE(xalt,yalt),v,pcolor,,,v/r
END IF
END IF
GOTO sh2
fillroutine:
PAINT(x,y),pcolor,fcolor
RETURN
colors:
IF POINT(x,y)>=0 THEN pcolor=POINT(x,y)
colors2:
LINE (0,186)-(25,195),pcolor,bf
LINE (0,186)-(25,195),fcolor,b
RETURN
size:
WINDOW 3,"Size",(0,0)-(200,30),16,1
PRINT "Width = ";wd
PRINT "Height = ";ht
PRINT "Press any key";
WHILE INKEY$="": WEND
WINDOW CLOSE 3
RETURN
test:
ERASE fd
DIM fd(FNe(wd,ht,sdepth))
GET (1,1)-(wd,ht),fd
CLS
LOCATE 10,5
PRINT "Working"
GOSUB BFormat
PAGE 62
-----------------------------------------------------------------------------
OBJECT SHAPE 1,a$
ON COLLISION GOSUB initobj
COLLISION ON
GOSUB initobj
OBJECT ON
FOR i = 0 TO 100
COLOR INT(RND*32)
LOCATE INT(RND*22)+1,RND*50+1
PRINT "EDDI II"
NEXT i
WHILE INKEY$ = "": WEND
OBJECT.OFF
OBJECT.STOP
COLLISION OFF
GOTO makescreen
initobj:
OBJECT.X 1,10
OBJECT.Y 1,10
OBJECT.VX 1,20
OBJECT.VY 1,15
OBJECT.START 1
RETURN
loader:
b = 1
MENU 3,gdep,1
CALL filename("Load",n$,b)
IF n$ = "" OR b=2 THEN RETURN
OPEN n$ FOR INPUT AS #1
IF b=0 THEN
INPUT #1,wd,ht,gdep
ERASE fd
DIM fd(FNe(wd,ht,sdepth))
FOR i = 4 TO FNe(wd,ht,sdepth))
INPUT #1,fd(i)
NEXT i
fd(1) = wd
fd(2) = ht
fd(3) = gdep
planepick = 2^gdep-1
ELSE
ColorSet = CVL(INPUT$(4,1)) ' These variables are not
DataSet = CVL(INPUT$(4,1)) ' used by this program.
gdep = CVL(INPUT$(4,1))
wd = CVL(INPUT$(4,1))
ht = CVL(INPUT$(4,1))
flags = CVI(INPUT$(2,1))
planepick= CVI(INPUT$(2,1))
planeonoff = CVI(INPUT$(2,1))
ERASE fd
DIM fd(FNe(wd,ht,gdep))
fd(1) = wd
fd(2) = ht
fd(3) = gdep
FOR i = 4 TO FNe(wd,ht,gdep)
fd(i)=CVI(INPUT$(2,1))
PAGE 63
-----------------------------------------------------------------------------
NEXT i
END IF
IF flags AND 1 THEN
fvsprite = 1
FOR i = 1 TO 31
a=CVI(INPUT$(2,1))
sr(i)=(a AND 3840)/3840
sg(i)=(a AND 240)/240
sb(i)=(a AND 15)/15
NEXT i
GOSUB fvsprite2
ELSE
collmask=(flags AND 2)/2
shadmask=(flags AND 4)/4
saveback=(flags AND 8)/8
overlay =(flags AND 16)/16
savebob =(flags AND 32)/32
MENU 4,1,1
MENU 4,2,1+collmask
MENU 4,3,1+shadmask
MENU 4,4,1+saveback
MENU 4,5,1+overlay
MENU 4,6,1+savebob
IF shadmask = 1 THEN
b=0:shad$=""
CALL filename("Shadowmask",shad$,b)
IF shad$<>"" THEN
OPEN shad$ FOR OUTPUT AS 2
PRINT #2,wd;ht;1;
END IF
FOR i = 4 TO FNe(wd,ht,1)
a = CVI(INPUT$(2,1))
IF shad$<>"" THEN PRINT #2,a;
NEXT i
IF shad$<>"" THEN CLOSE 2
END IF
IF collmask = 1 THEN
b = 0: coll$ = ""
CALL filename("CollisionMask",shad$,b)
IF coll$<>"" THEN
OPEN coll$ FOR OUTPUT AS 2
PRINT #2,wd;ht;1;
FOR i = 4 TO FNe(wd,ht,1)
PRINT #2,CVI(INPUT$(2,1));
NEXT i
CLOSE 2
END IF
END IF
END IF
CLOSE 1
GOTO makescreen
saver:
b=1
ERASE fd
DIM fd(FNe(wd,ht,sdepth))
GET (1,1)-(wd,ht),fd
PAGE 64
-----------------------------------------------------------------------------
CALL filename("Save",n$,b)
IF n$="" OR b=2 THEN RETURN
OPEN n$ FOR OUTPUT AS 2
IF b=1 THEN
GOSUB BFormat
PRINT #2,a$;
ELSE
PRINT #2,wd,ht,gdep
FOR i = 4 TO FNe(wd,ht,gdep)
PRINT #2,fd(i)
NEXT i
END IF
CLOSE 2
RETURN
BFormat:
a$=MKL$(0)+MKL$(0)
a$=a$+MKI$(0)+MKI$(gdep)
a$=a$+MKI$(0)+MKI$(wd)
a$=a$+MKI$(0)+MKI$(ht)
flags = fvsprite+2*vcollmask+4*shadmask+8*saveback
flags = flags + 16*overlay + 32*savebob
a$ = a$+MKI$(flags)
a$ = a$+MKI$(planepick)
a$ = a$+MKI$(planeonoff)
FOR i = 4 TO FNe(wd,ht,gdep)
a$=a$ + MKI$(fd(i))
NEXT i
IF shadmask THEN
IF shad$ = "" THEN GOSUB shad2
OPEN shad$ FOR INPUT AS 1
INPUT #1,b,h,t
IF b<>wd or h<>ht THEN
LOCATE 10,4
PRINT "Not in ShadowMask format!"
CLOSE 1
WHILE INKEY$ = "": WEND
GOTO makescreen
END IF
FOR i = 4 TO FNe(wd,ht,1)
INPUT #1,a
a$=a$+MKI$(a)
NEXT i
CLOSE 1
END IF
IF collmask THEN
IF coll$="" THEN coll2
OPEN coll$ FOR INPUT AS 1
INPUT 1,b,h,t
IF b<>wd OR h<>ht THEN
LOCATE 10,4
PRINT "Not in collision mask format!"
CLOSE 1
WHILE INKEY$="": WEND
GOTO makescreen
END IF
FOR i = 4 TO FNe(wd,ht,1)
PAGE 65
-----------------------------------------------------------------------------
INPUT #1,a$
a$ = a$+MKI$(a)
NEXT i
CLOSE i
END IF
IF fvsprite THEN
a$=a$+MKI$(INT(sr(1)*15)*256+INT(sg(1)*15)*16+sb(1)*15) 'sprcolor1
a$=a$+MKI$(INT(sr(2)*15)*256+INT(sg(2)*15)*16+sb(2)*15) 'sprcol2
a$=a$+MKI$(INT(sr(3)*15)*256+INT(sg(3)*15)*16+sb(3)*15) 'sprcolor3
END IF
RETURN
SUB planes(b$,p) STATIC
WINDOW 3,b$,(0,0)-(150,24),16,1
PRINT "End with <RETURN>"
p1: FOR i = 0 TO 4
LOCATE 2,2+i*2
PRINT i;
LOCATE 3,2+i*2
PRINT (2^i AND p)/2^1 ;
NEXT i
a$=""
WHILE a$=""
a$=INKEY$
WEND
IF ASC(a$)>=48 AND ASC(a$)<53 THEN p = p XOR 2^(ASC(a$)-48)
IF ASC(a$)<>13 THEN p1
WINDOW CLOSE 3
END SUB
SUB filename(b$,c$,d) STATIC
WINDOW 3,b$,(0,0)-(300,40),16,1
IF c$<>"" THEN
PRINT "Old "b$"Filename :"
PRINT c$
PRINT "<return> for same name"
END IF
INPUT "New Filename :",d$
IF d$<>"" THEN c$=d$
IF d=1 THEN
PRINT "Bob or Put Format"
INPUT "(b/p)";d$
IF d$="b" THEN
d=1
ELSE
IF d$="p" THEN
d=0
ELSE
d=2
END IF
END IF
END IF
WINDOW CLOSE 3
END SUB
PAGE 66
-----------------------------------------------------------------------------
The most important variables:
fd : Short integer array. This field stores the screen information and
is easily used with PUT and GET to display the graphic. fd(1) is
the width , fd(2) the height and fd(3) the depth. This size of
the array is self-defining using a function.
wd : Width of the graphic. Since our graphic always starts with 1,1
we can increase to the maximum whilst drawing.
ht : Height and last Y value of the graphic.
depth : Actual depth of the graphic. This value has no effect on the
screen depth.
sdepth : Actual depth of the screen. This value stays the same.
x : X coordinate when drawing.
y : Y coordinate when drawing.
xalt : Starting coordinate for drawing lines etc.
yalt : Y coordinate. Identical use as xalt.
pcolor : Actual drawing color.
fcolor : Color of the frame when filling. The fill function uses the
frame colour.
tool : The number of the actual drawing statement.
title : Number of the active menu.
pnt : Numbe of the active submenu.
b : Help variable for format decisions.
thick : Brush width for "Point"
n$ : Data name for loading and saving.
coll$ : Data name for the collision mask (See Below)
Shad$ : Data name for the shadowmask (See Below)
All object variables and flags will be explained in the following sections.
PAGE 67
-----------------------------------------------------------------------------
1.7.4.1 THE SCREEN
When you start the program your design board will appear on the screen
(Eddi's own window and screen). In this window you will see two things:
1.) all 32 colors in small boxes at the bottom of the screen and
2.) a large window frames in white. This window is where you can design
all your objects.
---------------------------------------------
1.7.4.2 OBJECT SIZE
The first thing you should do is set the size of the object. You can change
this size later, but you should have an idea of the form and size you want
before you start.
To find out the current size of your object, activate the menu item SIZE in
the WINDOW menu, which displays the width and height. You can change these
values in two different ways by using the keyboard.
1.) The cursor keys. The size of the object is increased or decreased.
2.) First press the help key and then use the mouse pointer to indicate the
new lower right hand corner of the object.
The top left hand corner of the object is always in the top left hand corner
of the screen and cannot be changed. You can shrink both height and width
all the way down to one. You can even define an object as small as one pixel.
This is the smallest possible object.
The maximum size of 312*184, if you have enough memory, is large enough for
most uses.
PAGE 68
-----------------------------------------------------------------------------
1.7.4.3 DEPTH
Depth is also important to the format of your object because it determines
the maximum number of colours the object can have. For example, with a
depth of five you can have up to 32 colours. Depth is processed in a special
way in this program and has its own menu that allows you to check or change
the current depth.
A checkmark in the depth menu indicates the actual depth. You can change this
the same way you select items in the workbench menus.
When you change the depth, the number of available colours and the length of
the colour bar also changes. Any full colour object that you currently have
in the design window is also affected.
----------------------------------------
1.7.4.4 COLORS
Look closely at the row of available colors and you can see that the first
square is slightly larger than the rest. This square indicates the current
drawing color. To select a different drawing color just click with the
mouse button on the color you want.
-------------------------------------------
1.7.4.5 DRAWING
Finally we have reached the main part of the program: Drawing. There are six
drawing modes located in the "tools" menu. This menu contains just about
everything you will need to draw wonderful pictures. To find the graphic
statements we have already discussed, look through the program listing.
All of the following statements use the current selected colour:
Points N POINT is a drawing statement you learned in some of the
demonstrations. When you click the left mouse button you will set
a pixel where the mouse pointer is located. This statement also
performs a special function. Instead of just setting pixels you
can set blocks of pixels 9*9 in size. The number after "point"
determines the brush size and can be changed from the keyboard
using the number keys (0-9).
PAGE 69
-----------------------------------------------------------------------------
LINES : The menu item works exactly like the Basic LINE statement. You
click and hold the left mouse button wherever you want to start
a line, then move to where you want the line to end and release
the button. Whil you hold the button, the start and end points
of the line will blink. This allows you to easily determine the
direction and level of the line.
FRAMES : This statement draws an unfilled rectangle. You set the upper
left and lower right hand corners in the same way you set the
ends of the line above.
BOXES : Boxes performs the opposite of frames by drawing a filled
rectangle. You accomplish the sizing the same way.
CIRCLES : The circle menu item lets you set your parameters using the mouse
which is much easier than the BASIC method. Sizing is similar to
the line statement, but with circle, your start point will be the
centre of the circle. The points where you release the mouse
button sets the maximum height and width of the circle. However,
this release point is never part of the circle. The X and Y
difference in relation to the release point determines the
horizontal and vertical radius. Therefore, the two points you
set with the mouse mark exactly a quarter of the circle.
FILL : The lasst object fills any framed area. Unlike OBJEDIT , this
fill statement allows you to fill an area with a different color
than the frame of the area. When you select fill the program
automatically selects the drawing colour as the frame and fill
colour. If you select a different colour while "fill" is active,
the frame colour does not change. The program indicates the
current colour by a frame around the drawing colour and around
the object.
Use the DELETE option from the WINDOW menu to clear the screen when you are
not satisfied with an object design.
PAGE 70
-----------------------------------------------------------------------------
1.7.4.6 LOADING AND SAVING.
In order to keep your masterpiece you need load and save options. The BASIC
statements GET and PUT are perfect for this.
Actually, you can save and load your data in two different formats. The
first format uses the PUT statement to save data in short integer form.
As you saw in previous demonstrations, the data is easily loaded using the
PUT and GET statements and is displayed in original form on your screen.
The second format is designed for bobs and is used to create files for bobs
and sprites. Besides the raw picture information, these files contain many
other values for objects and are displayed using the OBJECT.SHAPE
statement.
The program remembers the last filename used for a load or save. To load
or save using the same filename you only have to press the <Return> key.
-----------------------------------------
1.7.4.7 TESTING OBJECTS.
The TEST option in the WINDOW menu enables you to test your new objects
without having to exit the editor. You can make quick changes easily if
the object is not exactly what you want.
You do not have to save an object to disk before testing it. We take the
data directly from the screen and convert it to the OBJECT.SHAPE statement
format. Therefore, you can test it out before you save it. To exit the test
mode press any key.
-------------------------------------------------
1.7.4.8 EXITING EDDI II.
Even when exiting the program has two options. You can select QUIT from the
window menu, or simply press the <q> key. Remember that exiting the program
clears all data so be sure you have saved your object first.
PAGE 71
-----------------------------------------------------------------------------
Upon exiting, the window and screen for the program are closed and the
normal BASIC menus are activated again.
--------------------------------------------
1.7.4.9 LOADING OBJECTS INTO YOUR PROGRAMS.
To load the objects as bobs you must save them in bob format. Then it is
quite easy to load them again using the OBJECT.SHAPE statement.
OPEN "filename" FOR INPUT as 1
OBJECT.SHAPE 1,INPUT$(LOF(1),1)
CLOSE 1
--------------------------------------------
1.7.5 FLAGS.
The flags determine the appearance of an object on the screen. Each flag
has two possible settings. It is either set and equals 1 or not set and
equals zero. Several flags are combined into one byte and all flags are
passed to the computer in the character string that is used with the
OBJECT.SHAPE statement. Once set, flags cannot be modified from BASIC.
Our editor has it's own menu for the flags. Set flags are indicated by a
small check in the menu.
There are two other functions in the FLAG menu besides the flags:
PLANEPICK and PLANEONOFF. We will explain a bit later what these two do.
--------------------------------------------
1.7.5.1 THE SAVEBACK FLAG.
We will discuss the SaveBack flag first because it is the simplest one. All
flags have names that help you remember what they do. For example, SaveBack
is an abbreviation for "save the background".
When you draw a bob it becomes part of the existing screen. What was on the
screen is painted over. To save and restore what the bob covers when it is
moved, you have to set the SaveBack flag.
PAGE 72
-----------------------------------------------------------------------------
When the SaveBack flag is not set and you move the object, the original
object image will still be on the screen. Test this out with one of your
objects in the editor.
When this flag is set and you are moving large objects, there will be a
flickering on the screen. Also, screens with a lot of depth will have the
same effect. Since there is no way to counter this flicker while using
BASIC, you should set this flag only if you really need it.
At this point we need another sample program. To keep our program short,
we have used smaller objects. The number of data statements required for
biger objects would make this demonstration program too large.
REM 1.7.5.1 Airplane.
DEFINT a
SCREEN 1,320,200,2,1
WINDOW 2,,,16,1
PRINT "Reading in DATA ......."
FOR i = 1 TO 313
READ a
a$ = a$+MKI$(a)
NEXT i
LOCATE 10,1
PRINT "In this Object demo you will see an"
PRINT "airplane that flies accross the"
PRINT "screen, without having any effect"
PRINT "on this text."
OBJECT.SHAPE ,a$
OBJECT.SHAPE 1,a$
ShowOBJ:
OBJECT.X 1,1
OBJECT.Y 1,80
OBJECT.VX 1,3
OBJECT.VY 1,20
OBJECT.AX 1,4
OBJECT.AY 1,-2
OBJECT.ON
OBJECT.START
WHILE INKEY$ = "":WEND
GOTO ShowOBJ
REM Data for the airplane.
DATA 0,0,0,0,0,2,0,88,0,25
DATA 8: REM This is the value for thew flags.
DATA 3,0,8160,0,0,0,0,0,16368,0,0,0,0
DATA 0,16376,0,0,0,0,0,16380,0,0,896,0
DATA 0,16382,0,0,-1,-32768&,0,16382,0,1,-28668,-16384
DATA 0,16383,0,3,4100,24576,0,16383,0,6,4100,12288
DATA 0,16383,-32768,12,4100,6144,0,16383,-16384,24,4100,3072
DATA 0,16383,-16384,48,4100,2044,0,16383,-2048,127,-1,-1
DATA 0,16383,-1,-1,-1,-14337,0,16383,-1,-1,-2048,12543
DATA 0,16383,-1,-4,-1023,-385,0,4095,-1,-31,-1,-129
DATA -32768,4095,-1,-497,-1,-129,-32768,1023,-1,-257,-1,-129
PAGE 73
-----------------------------------------------------------------------------
DATA -32768,1023,-1,-257,-1,-129,-32768,1023,-1,-129,-1,-385
DATA -32768,511,-1,-249,-1,-257,0,7,-1,-32,0,504
DATA 0,0,0,16383,-1,-32,0,0,0,0,2044,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,8176,0,0,0,0
DATA 0,1536,0,0,28667,0,1024,1648,0,0,-4101,-32768
DATA 1024,1736,0,0,-4101,-32768,1024,1728,0,0,28667,8192
DATA 1024,1728,0,0,28667,-32768,1024,1728,0,0,28667,-32768
DATA 1024,1728,0,0,0,0,1024,1736,0,0,0,0
DATA 2048,1648,0,0,0,0,2048,0,0,0,0,0
DATA 14336,0,0,0,0,127,-2048,0,0,0,0,127
DATA -2048,3,-1,-512,0,0,26624,1023,-1,-512,0,0
DATA 2048,0,0,256,0,0,3072,0,0,0,0,0
DATA 1024,0,0,0,0,0,1024,0,0,0,0,0
DATA 1024,0,0,0,0,0,1024,0,0,0,0,0,1024
We have included the OBJECT statements in this program. You have to use most
of these statements for any object. Here are the individual explanations:
OBJECT.SHAPE : The character string a$ contains all the necessary
information you have to pass to the computer. When you want
to use an object you must specify the number assigned to it
with OBJECT.SHAPE. In our program that number was 1.
Previously we demonstrated how you load the object data from
disk.
OBJECT.X/Y With these statements you set the start position.
The first parameters sets the object numbers.
OBJECT.VX/Y This statement sets the speed (velocity) for the selected
object.
OBJECT.AX/Y The velocity of an object does not have to be constant.
You can set an acceleration factor with this statement.
OBJECT.ON Makes the specified object visible on the screen.
OBJECT.START Even though you have set a velocity and acceleration for your
object, it will not move until you execute this statement.
This program is a very good demonstration of the SaveBack flag. The text
remains visible even though the airplane flies right over the text.
PAGE 74
-----------------------------------------------------------------------------
If you want to see what happens when the SaveBack flag is not set, change
the 11th value (the only value in the second DATA line) in the data list.
Change the eight to zero> Now when you run the program one corner of the
airplane will leave a trail on the screen.
--------------------------------------------
1.7.5.2 SAVEBOB.
The SAVEBOB flag is almost the opposite of SaveBack flag. When you set
SaveBob, the object remains on the screen. You might be familiar with this
effect from some of the better paint programs. This method allows you to
draw while an object is on the screen.
--------------------------------------------
1.7.5.3 OVERLAY.
In our last sample program you probably noticed that when the airplane
flew over the text it covered a much larger size than the actual area of the
airplane. This effect can be removed with the overlay flag. When the overlay
flag is set, all the unset pixels of the object become transparent. You can
then see the background through the object wherever there are no set pixels.
To test this out on our airplane, set the overlay flag by adding 16 to the
eight of the SaveBack flag. The new flag becomes 24 and both flags are
active.
This is only one of many possibilities you have with Overlay. The other uses
are connected to the shadow mask.
--------------------------------------------
1.7.5.4 THE SHADOW MASK.
The SHADOW mask is one of two masks that you can define for each object.
With the SHADOW mask you can specify which pixels the background covers and
which pixels only change the colour of the background. Also, if you have
set the Overlay flag, the Shadowmask determined which pixels of the object
are visible.
The mask must have the same width and heightas the object you use with it.
In format, a mask and object are the same, except the mask depth is
independant of the object depth. Each bit in the mask is equal to one pixel
of the object. If a bit in the mask is set, the corresponding pixel in the
object is on top of the background.
PAGE 75
-----------------------------------------------------------------------------
The Overlay flag handles unset pixels. If the overlay flag is set, the
object pixel has no effect on the background. If the overlay flag is unset,
the colour of the background pixel is changed.
If the OVerlay flag is set the computer will create a default shadow mask
(if you have not created one). In this mask, all bits are set to match the
set pixels of the object. This makes all the unset pixels of the object
transparent.
When you want to create your own SHADOW mask with the editor you should use
the following steps:
1. First you must already have an object for the mask. The best way to do
this is to load your object first which gives you the correct format for
the mask.
2. Set the depth to one.
3. Draw the mask. Any remaining pixels from the object can assist you with
this.
4. Save the mask to disk in P format.
5. Load the object that the mask is for again.
6. Now set the Shadowmask flag on, in the FLAGS menu and enter the name used
to save your mask.
7. Save the object in B format or test it
Of couse if you already have a mask designed you can skip the first 5 steps
of the list.
--------------------------------------------
7.5.5 COLLISIONS.
The second mask is the COLLISION mask. This mask, which has nothing to do
with the OBJECT.HIT statement which we will discuss later, determines where
the computer "senses" a collision. When the Collision mask is empty, the
computer cannot see a collision. When you define a collision mask, the set
bits of the mask are the sensitive points.
You can design and install a collision mask in the same way as the Shadow
mask. If you don't define a Collision mask, the computer will use a default
collision mask. The default mask is built by using a logic OR function on
all the bit-planes of the bob (exactly like the shadow mask). The computer
then reacts to contact with any set pixel of the object.
PAGE 76
-----------------------------------------------------------------------------
In our next program we'll demonstrate other methods, other than using the
COLLISION mask for controlling collisions. Well test these statements using
two squares that move around the screen.
REM 1.7.5.5 COLLISION.
DEFINT a
RANDOMIZE TIMER
SCREEN 1,320,200,2,1
WINDOW 2,,,16,1
PRINT "Reading in Data.... "
FOR j = 1 TO 2
FOR i = 1 TO 13
READ a
a$(j) = a$(j)+MKI$(a)
NEXT i
a$(j)=a$(j)+MKI$(-1)+MKI$(-1)
FOR i = 1 TO 30
a$(j) = a$(j) + MKI$(-32768&)+MKI$(1)
NEXT
a$(j) = a$(j) + MKI$(-1) + MKI$(-1)
NEXT j
FOR i = 1 TO 30
a$(2)=a$(2)+MKI$(0)
NEXT i
a$(2) = a$(2) + MKI$(1)+MKI$(-32768&)
a$(2) = a$(2) + MKI$(1)+MKI$(-32768&)
FOR i = 1 TO 30
a$(2) = a$(2)+MKI$(0)
NEXT i
CLS
OBJECT.CLIP (70,30)-(230,190)
LINE (70,30)-(230,190),3,b
ON COLLISION GOSUB collroutine
COLLISION ON
OBJECT.SHAPE 1,a$(1)
OBJECT.SHAPE 2,a$(2)
OBJECT.PRIORITY 1,1
OBJECT.HIT 1,3,2
OBJECT.HIT 2,2,2
OBJECT.X 1,150
OBJECT.Y 1,80
OBJECT.X 2,155
OBJECT.Y 2,85
OBJECT.VX 1,8
OBJECT.VY 1,4
OBJECT.START 1,2
OBJECT.ON 1,2
WHILE INKEY$ = ""
LOCATE 2,15
PRINT OBJECT.X(1);TAB(21);OBJECT.Y(1)
PRINT TAB(15);OBJECT.X(2);TAB(21);OBJECT.Y(2)
WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
END
PAGE 77
-----------------------------------------------------------------------------
collroutine:
n=COLLISION(0)
m=COLLISION(n)
more:
IF n=1 and m<0 THEN
BEEP
IF ABS(m) MOD 2 = 0 THEN
OBJECT.VX 1,(m+3)*(RND*20+1)
ELSE
OBJECT.VY 1,(m+2)*(RND*20+1)
END IF
END IF
OBJECT.VX 2, OBJECT.VX(1)+3*SGN(OBJECT.X(1)-1-OBJECT.X(2))
OBJECT.VY 2, OBJECT.VY(1)+3*SGN(OBJECT.Y(1)-1-OBJECT.Y(2))
OBJECT.START
n=COLLISION(0)
m=COLLISION(n)
IF m<>0 THEN more
RETURN
DATA 0,0,0,0,0,1,0,32,0,32
DATA 24,1,0
DATA 0,0,0,0,0,1,0,32,0,32
DATA 10,1,0
While the two squares dash around the screen, we can display their
coordinates by using the OBJECT.X function. Or you could also display the
object's velocity using the OBJECT.VX funtion. The same function is
available for the Y direction. These functions are very important when you
want a program to react to a collision in a certain way.
In order for a collision to occur, you always need two things. In our
program we hae two objects, both objects are squares, the same size, the
same colour, and are only a frame. Even though the objects seem similar they
have differences. Since we did not specify a collision mask for the first
object, the computer provides a default collision mask using the OR function
on its bit-planes. The collision mask consists of only the frame of the
object.
For the second object we design our own collision mask. In this mask we
set only the four centre pixels of the object. The program places the
second object inside the first and whenever the second object tries to
escape from the first there is a collision.
By using the OBJECT.CLIP statement, we confined the first object to a
specific screen area. Because of this, the first object cannot move just
anywhere on the screen.
Without the COLLISION functions, we would not be able to react to a
collision. The three COLLISION functions are the only object related
statements that do not begin with OBJECT. The first statement, ON
COLLISION GOSUB, tells the computer where to branch. However, this
statement will not function without the second statement COLLISION ON,
which tells the computer that, if there is a collision , then branch.
If COLLISION ON has not been used, the object will simply stop moving
at the border of the specified area.
PAGE 78
-----------------------------------------------------------------------------
The third function helps us determine which two objects have collided. You
can read the first object number with COLLISION(0) and the second object
number with COLLISION(n). The n must be the number of the object that was
involved in the collision. To determine the other object involved in the
collision, substitute COLLISION(0) for the (n) in the COLLISION function.
The value that is returned is the number of the second object. A collision
with the border will return a value smaller than one.
COLLISION (COLLISION(0)) Border.
---------------------------------------
-1 top
-2 left
-3 bottom
-4 right
Sometimes it is possible for the second bob to escape from the first bob.
When the second object's speed is very fast, the collision mask can
jump over the other object's mask without touching it. Because the border
does not affect it, the second bob can leave the defined screen area and
enclose the first object. To determine which collision will cause this
breakout use the OBJECT.HIT statement. Specify two 16-bit masks. The first
is named the MeMask and the second is named the HitMask. When two objects
collide with another, the MeMask of one is compared with the HitMask of
the other. If both masks have a one in the same position, a program
interrupt occurs. An interrupt will also happen when an object's
HitMask is set equal to one and it collides with a window or area border
set with OBJECT.CLIP.
Instead of using a bit pattern, you set these masks using a number between
-32768 and +32767. The default value of these masks is -1 which means a
full mask. The end result is an interrupt on any collision.
The final new statement in the program does not have a direct connection to
collisions. This statement lets you specify the sequence in which to draw
the objects on the screen. This is mostly important for deciding which
objects are to appear first. The statement is OBJECT.PRIORITY and uses
a default value of zero. The higher the priority number, the earlier an
object is drawn.
PAGE 79
-----------------------------------------------------------------------------
5.6 ANIMATED BIT-PLANES.
We have mentioned many times that the graphic information of an object is
divided among different bit-planes. We mean that every screen pixel is made
up of many different bits in memory that determine the pixel's colour. The
depth is determined by how many bits are available for use per pixel. The
first bit of all pixels builds the first bit-plane, the second bit builds
the second plane and so-on.
All bit-planes are stored one after another in memory. This gives you a
special advantage, particularly when using objects, because you can easily
add or delete a bit-plane without affecting your objects. You can also
define objects that have less depth than the screen. For example, you could
use a screen depth of 5 and an object with a depth of two. With this depth,
your object could only have four colours but these colours can be any 4
of the screen's 32.
There are two statements that enable you to play with the object colour
combinations that are possible with a palette of 32 colours. By using the
same object from our last program we can demonstrate this.
REM 1.7.5.6 OBJECT.PLANES statement
SCREEN 1,320,200,5,1
WINDOW 2,"Planes-Demo",,31,1
FOR i = 1 TO 61
READ g
p$=p$+MKI$(g)
NEXT i
OBJECT.SHAPE 1,p$
OBJECT.ON
x=50
y=5
FOR i = 0 TO 3
FOR j = i+1 TO 4
IF j<>i THEN
FOR k = 0 TO 31
IF (k AND 2^i OR k AND 2^j)=0 THEN
OBJECT.X 1,x
OBJECT.y 1,y
OBJECT.PLANES 1,2^i+2^j,k
x=x+20
IF x>244 THEN
x=50
y=y+20
END IF
END IF
NEXT
END IF
NEXT j
NEXT i
PAGE 80
-----------------------------------------------------------------------------
LOCATE 22,5
PRINT "80 different colour combinations"
WHILE INKEY$="": WEND
WINDOW CLOSE 2
SCREEN CLOSE 1
DATA 0,0,0,0,0,2,0,16,0,16,52
DATA 0,0,-8180,-8082,-8081,-8081,-8177
DATA -1,-1,-1,-1,-1,-1,-1025,-1105,-681
DATA -2049,-1,-4,-2,-1,-1,-1,-1,-1,-1,-1
DATA -1,-16381,-16381,-16381,-16381
DATA -16381,-16381,-4,-2,-1,-1,-1,-1,-1
DATA -1,-1,-1,-1,-1025,-1105,-681,-2049
DATA -1
As you can see, there are 80 possible combinations. We will explain why
there is only 80 later on. First we want to show you how to achieve these
combinations. There are two values in the object structure that make this
possible. The first value tells us what bit-plane is being written to. The
bit-plane determines the order of the five bits of a pixel and also the
colour in which it appears. The value is named PlanePick and you will find
it in our editor under the FLAGS menu.
There are tem possible combinations for a two depth bob, in a screen with a
depth of five:
1. 11000 0,1,2,3
2. 10100 0,1,4,5
3. 10010 0,1,8,9
4. 10001 0,1,16,17
5. 01100 0,2,4,5
6. 01010 0,2,8,9
7. 01001 0,2,16,17
8, 00110 0,4,8,9
9. 00101 0,4,16,17
10. 00011 0,8,16,17
After each of the ten combinations we have listed the colour registers that
the computer uses when you write to other bit-planes. In the number series
made up of ones and zeros, a one means that a plane will be written in that
bit-plane. The first plane of an object will be the first selected plane
of the screen. PlanePick is not limited to spreading two planes over five
bit-planes. It works just as well with fewe or more planes.
As explained above, our editor determines the selected plane through a
series of ones and zeros. When you checked the menus for PlanePick you
probably got an idea about the second method for changing colours. Directly
under PlanePick in the menus is the statement PlaneOnOff.
PAGE 81
-----------------------------------------------------------------------------
This statement sets a value in the object structure that determines what
happens in the unselected screen planes. All planes not used by PlanePick
are considered unusud. As the name indicates you use PlaneOnOff to turn
planes on and off. You already know about the off status since this is the
normal condition for an unused plane. When you switch on a bob in an unused
plane a shadow mask is written to that plane. In other words, when a
bit-plane is set to on, and the shadow mask contains a matching bit for a
pixel, that pixel's colour will change.
The construction of PlaneOnOff is the same as PlanePick. Unlike the flags,
the value assigned using the editor can be changed later, otherwise our
colour combination program would be more complicated. We use the
OBJECT.PLANES to set both of these values. This is the sequence you pas
the values: object number, PlanePick and PlaneOnOff. Again, you cannot
simply enter the binary number sequence, you have to calculate the
values. The following formula does this:
PlanePick = b1+2*b2+4*b3+8*b4+16*b5
All you have to do is replace b1 thru b5 with the converted binary sequence.
The formula for PlaneOnOff is the same.
PlanePick and especially PlaneOnOff, open up unexpected methods for
animation. From one bob you can create many different figures. Using this
method we have created an olympic torch on the screen. The flickering
flame and different colours are created by changing PlanePick and
PlaneOnOff.
REM 1.7.5.6B Fire
DEF FNplanes=CINT(RND)*4+CINT(RND)*8+CINT(RND)*16
FOR i = 1 TO 274
READ a
a$=a$+MKI$(a)
NEXT i
SCREEN 1,320,200,5,1
WINDOW 2,,,,1
PALETTE 0,0,0,0
PALETTE 4,1,.5,0
PALETTE 8,1,0,0
PALETTE 12,1,.26,0
PALETTE 16,1,.4,0
PALETTE 20,.8,0,0
PALETTE 24,.95,.5,0
PALETTE 28,1,.9,0
LOCATE 2,5
PRINT "The Eternal Flame"
LINE (96,120)-(110,180),26,bf
CIRCLE (103,70),60,27,4.02,5.4
LINE (66,108)-(140,108),27
OBJECT.SHAPE 1,a$
PAGE 82
-----------------------------------------------------------------------------
CLOSE 1
OBJECT.X 1,79
OBJECT.Y 1,79
OJECT.ON 1
fire:
a=FNplanes
IF a = 28 THEN a = 24
OBJECT.PLANES 1,a
FOR i = 0 TO 10: NEXT
OBJECT.PLANES 1,,FNplanes
FOR i=0 TO 10: NEXT
GOTO fire:
REM flame DATA
DATA 0,0,0,0,0,2,0,48,0,29
DATA 12,24,0,0,0,0,0,0,0,0
DATA 0,0,0,0
DATA 0,0,0,0,0,0,0,0,0,0
DATA 0,0,0,0,0,0,0,96,0,0
DATA 0,0,0,1152,16384,0,1665,-16384,32,1792
DATA -16384,16,1671,-32768,48,902,0,18,5661,-32768
DATA 26,-30194,128,12,-20869,256,7,-14609,-13824,3
DATA 15999,-15872,0,-257,-17664,0,-1554,23040,0,-7434
DATA -8704,0,-18441,5120,0,27399,18432,0,30230,16384
DATA 0,29704,16384,0,-32752,0,0,0,0,0
DATA 0,0,0,0
DATA 0,0,192,0,0,320,0,0,320,128
DATA 0,480,1920,0,416,7680,256,1888,16128,896
DATA 1664,-1024,896,16353,-9216,992,-16607,-208,976,-20702
DATA -2044,504,32727,26652,404,8013,26728,252,4991,29040
DATA 210,15420,31728,122,-21928,-3088,77,-21544,16128,46
DATA 8360,8896,50,56,960,10,-32176,8384,10,-16384
DATA -32640,6,12,-24320,5,271,8192,2,-31244,-32768
DATA 0,-32657,-26624,0,-32745,12288,0,0,8192,0
DATA 2,0,0,6
DATA 0,0,6,0,0,7,0,0,3,0
DATA 0,9,0,0,11,256,0,10,768,1
DATA 28,3328,1,26,4608,2,62,8704,2,206
DATA 8704,6,460,30208,6,460,28160,15,510,17920
DATA 31,3486,-31744,4,-27235,19968,20,21022,19456,5
DATA 13132,7168,21,-26168,12288,7,-25524,-4096,1,22590
DATA 28672,2,-10628,20480,3,-3279,0,1,29903,-20480
DATA 0,19525,12288,0,11577,0,0,1033,0,0,11777,0
PAGE 83
-----------------------------------------------------------------------------
Our flame uses only eight different colors that come from registers 0,4,8,
12,16,20,24 and 28. These are the only colours changed, all others are free
for use.
It is possible for the flame to have multiple combinations of the two planes
and the shadow mask. PlanePick could select both planes at the same time. It
is also possible that only one, or none, of the planes will be drawn.
PlaneOnOff can also set unused planes on.
All of this is arranged with very little effort. These methods can be
applied to many different types of objects. For example, an exploding
spaceship, the winking of an eye or lip movement, and much more can be
packed into an object.
PAGE 84
-----------------------------------------------------------------------------
1.7.6 THE ALTERNATIVE : SPRITES.
We have not said much about sprites so far in our discussions of animation.
Sprites are controlled in a similar way that bobs are controlled. The
same BASIC statements that apply to bobs also apply to sprites.
-----------------------------------------------
1.7.6.1 THE SMALL DIFFERENCE.
To design a sprite with our editor all you have to do is set the sprite flag
in the FLAG menu. When you do this all the other menu items will become
ghost selections. You will not be able to use them because they have no
effect on sprites. Sprite characteristics are determined by the settings of
the OverLay and SaveBack flags.
The properties of sprites are very specific. A sprite can never be more than
16 pixels wide and can only have three colours. The height is not limited.
Sprites can move much faster than BOBS.
-----------------------------------------------------
1.7.6.2 COLOUR AND SPRITES.
In contrast with bobs, a sprites' colour has no direct connection to the
screen depth. Sprites carry their own colour information which is not
stored in any registers (there are no more than 35 possible colours).
The colours carried by as sprite can affect the screen colours that are
covered by it. When a sprite is on top of or behind a pixel, the colour
register for that pixel will cause a color change.
You cannot chose which register a sprite stores its colours. However, you
can choose which colours the sprite uses. When you have the sprite flag set
you can select "spr.color" from the menu to pick three colours for the
sprite. The values are assigned the same way as with PALETTE>
PAGE 85
----------------------------------------------------------------------------------------------------------------------------------------------------------
CHAPTER 2 - AMIGA OPERATING SYSTEM
So far our programs have worked well using only the everyday BASIC
statements. However, at this point BASIC alone is not enough. Our next
series of projects requires capabilities that BASIC cannot provide. These
capabilities include a graphic hardcopy routine, new character sets,
1024*1024 pixel superbitmap graphics, and much more.
With most computers you would have to write machine language programs in
order to perform additional functions and statements. This is not required
with the Amiga because the solutions for our next projects are resident in
the Amiga operating system and the Amiga operating system libraries. Each
library consists of hundreds of small machine language routines. These
routines are organised by functions and can handle just about any
operation. So, with the Amiga, you do not have to create new commands, you
only have to learn how to use the libraries.
The procedure for accessing libraries is built into AmigaBASIC, the
statements "LIBRARY" and "DECLARE FUNCTION (.....) LIBRARY" are used to
access the libraries. In order to access these libraries we use a .bmap
file. For every system library, you create a matching .bmap file which
contains the names of all machine language library routines and other
necessary parameters. By using the ConvertFD program on the extra disk, you
can quickly create all the required .bmap files. See the ABOUTBMAPS program
on your extras disk for more information on creating the .bmap files.
Before you read any further, you should generate the following ".bmap"
files:
.bmap files
--------------------
graphics.bmap
exec.bmap
layers.bmap
intuition.bmap
diskfont.bmap
dos.bmap
You should copy these files to your LIBS directory on the Workbench disk.
You can also use these files by having them and your program files in one
directory on the same disk.
PAGE 87
----------------------------------------------------------------------------
Now that we have finished the groundwork we can move onto the programming.
The LIBRARY and DECLARE FUNCTION (....) LIBRARY statements are our tools.
Before you can use one (or more) of the system libraries, you have to open
them. We use the LIBRARY statement to do this:
LIBRARY "graphics.library"
When AmigaBASIC receives this command, BASIC looks for the definition file
graphics.bmap. If this file is not found in the current directory, BASIC
will look for it on the Workbench disk in the LIBS directory. When BASIC
doesnt find the .bmap file there, you will get a "file not found" error. As
you can see, in order to run your program, it is important that the .bmap
file is available.
When basic finds the .bmap file, it opens the appropriate system library.
From this point on, BASIC will compare the program function calls with the
graphics.bmap function list. The requested routines are executed from the
library when they are called.
The next program is a small deminstration of how this works. The function
we want to use is in the graphics.library and is called TEXT. This routine
prints a text string of any length on the screen. There are three required
parameters:
1.) The address of the RastPort (to be discussed shortly)
2.) the address of the text.
3.) the length of the text.
REM 2a. Hello World.
LIBRARY "graphics.library"
a$="Hello World!"
length% = LEN(a$)
rastport& = WINDOW(8)
CALL Text(rastport&,SADD(a$),length%)
LIBRARY CLOSE
Enter this program very carefully because system libraries are very
sensitive to errors. When the program starts, it will look for the
graphics.bmap file. In a few moments the message, "Hello World!" will
appear in the upper left hand corner of the screen. The statement LIBRARY
CLOSE closes the library, but it is not required because BASIC will
automatically close any open libraries any time you use the RUN or NEW.
We like to explain the statement SADD(a$) and the variable rastport& used
in the above program. The statement SADD passes the memory address of the
of the text string a$. The TEXT routine then uses this address to read the
text. RastPort indicates which drawing plane tO use.
PAGE 88
----------------------------------------------------------------------------
We will explain this in more detail later. What you need to understand now
is that the RastPort address tells the computer the window in which to
display the text. The actual window address is in the variable WINDOW(8).
The above program only demonstrated how to use a library. You could have
easily accomplished the same thing with a normal PRINT statement. The next
program has a SUB routine named "p" that uses the TEXT routine and is
simply a faster replacement for PRINT. To call it:
P "text",mode%
mode% 0 = PRINT "text";
1 = PRINT "text"
'##########################################
'#
'# Program: Quick Print.
'# Date : 04/13/87
'# Author : tob
'# Version: 1.0
'#
'##########################################
PRINT "Searching for the .bmap file ..."
'GRAPHICS-LIBRARY
'Text()
LIBRARY "graphics.library"
demo: demo$=STRING$(80,"*")
CLS
'* Quick print.
PRINT "QUICK PRINT:"
FOR loop1%=0 TO 10
P demo$,1
NEXT loop1%
'* Normal Print
PRINT "AmigaBASIC's normal PRINT:"
FOR loop2% = 0 TO 10
PRINT demo$
NEXT loop2%
LIBRARY CLOSE
SUB P(was$,mode%) STATIC
CALL Text(WINDOW(8),SADD(was$),LEN(was$))
IF mode% = 1 THEN PRINT
END SUB
This new routine is three times as fast as PRINT. The text appears
immediately, not line by line. If you add an LPRINT to the SUB P routine,
much more is possible. You could PRINT and LPRINT all text without using an
LPRINT after each print in your program.
We are finished with our first useful application of the system libraries.
Hopefully, you are now curious about the many other possibilities.
PAGE 89
-----------------------------------------------------------------------------
Our introduction is not quite complete because the DECLARE FUNCTION (....)
LIBRARY statement was not included in our demonstration program. The TEXT
routine uses a CALL statement since the libraries performed any required
actions without having to return a result to BASIC; therefore a DECLARE
statement was not needed. Functions that have to return a result to BASIC
must use the DECLARE statement. For example, one of these functions from
the graphic library is READPIXEL. READPIXEL requires several parameters:
the address of the RastPort (a pointer to the desired window), and a X and
Y coordinate. The value that is returned to the program by READPIXEL is the
colour of the specified pixel. To use this function you must use the
DECLARE statement:
REM 2c DECLARE
DECLARE FUNCTION ReadPixel% LIBRARY
LIBRARY "graphics.library"
x%=320
y%=125
rastport&=WINDOW(8)
colour% = ReadPixel%(rastport&,x%,y%)
PRINT "Found Colour Number";colour%
LIBRARY CLOSE
ReadPixel is declared as a function in the first program line because, when
called, it returns a value to the program. The "%" character ater READPIXEL
in the function definition, declares the value returned by READPIXEL to be
of type integer. From this point on, the routine is called using the name
READPIXEL%.
This completes our explanation of the basic principles involved in using
libraries. You know how to open a library and how to access a routine in
it. The following pages provide details on what routines the various
libraries have and what parameters are required. AmigaBASIC can open and
access up to 5 libraries at the same time. You should always remember that
the routines in these libraries are machine language programs. Even though
they are a bit more difficult to use, these routines are much faster than
pure BASIC. Also remember that these routines do not check for incorrect or
invalid parameters, so one small mistake, an invalid parameter or a wrong
call can cause the system to crash. You would then have to reboot from the
Workbench and all programs in memory are lost.
Enter all your programs carefully and save them to disk before you test
them.
The following program IBRARY "graphics.library"
a$="Hello World!"
length% = LEN(a$)
rasport& = WINDOW(8)
'* Above is the error (rasport& instead of
'* rastport& so rastport& = 0
CALL Text(rastport&,SADD(a$),length%)
LIBRARY CLOSE
If you run this program you will receive the following message or the
system will lock up completely:
Software failure. Click left mouse button to continue.
Guru Meditation #00000004.00xxxxx
Follow the instructions, or perform a warm reset by pressing both <A> Amiga
keys and the <Ctrl> key at the same time.
PAGE 91
-----------------------------------------------------------------------------
Now load part 2
-----------------------------------------------------------------------------